stackedit_在StackEdit中实现TitleCapitalization

stackedit

在SitePoint上为PHP Channel撰写帖子时,我经常忘记如何正确使用标题。 我通常最终会使用TitleCapitalization进行快速修复,但是我常常幻想在StackEdit的title字段旁边有一个按钮来快速自动应用。 好了,我们已经介绍了启动和运行本地(或多个)StackEdit的问题。 为什么也不要构建按钮?

03

准备好

为了准备升级,我们需要签出StackEdit的本地副本。 我当然会使用我可信赖的旧版宅基地改良盒,就像这里一样。 您可以使用自己的Linux操作系统,具体取决于您,但这绝对是最简单的。

git clone https://github.com/swader/homestead-improved hi_stackedit
cd hi_stackedit
vagrant up
vagrant ssh

进入虚拟机后,我们将克隆StackEdit。

cd ~/Code
git clone https://github.com/benweet/stackedit
cd stackedit
npm install --no-bin-link

请注意,如果在运行此命令时遇到“无法解决”错误,并且以典型的节点“冗长”的方式出现了许多其他错误,则仅意味着某些依赖项丢失了。 进入package.json并从第23 第28 删除主题标签值(如果它们仍然存在)。 这些标记引用的版本不再存在,并且在撰写本文时,StackEdit的作者仍未更新StackEdit的文件以反映这一点。

bower install

这需要一段时间。 如果安装了BowerPHP ,则可以使用它。

要运行本地副本,请执行以下操作:

(export PORT=5000 && node server.js)

然后,在浏览器中访问homestead.app:5000 (或您设置的任何主机,如果不是默认的homestead.app )。

实作

好吧,让我们开始吧。 该实现将由两部分组成-UI和逻辑。

用户界面

让我们添加按钮。

StackEdit在UI方面有些复杂,难以扩展。 安装后,项目本身包含超过30000个文件,其中包含下载的依赖项和批次。 这对于Web应用程序来说是荒谬的,并且对于任何IDE都很难索引,尤其是因为JavaScript有点混乱。 向界面添加按钮需要几个步骤。 我们要寻找的外观是这样的:

02

文档标题旁边的“复选标记”图标,形式为Glyphicon ,根据使用的主题与其他UI匹配。 我使用复选标记是因为Glyphicons已包含在StackEdit的Bootstrap中。 在上下文上可能并不完美,但这是在不编辑太多文件的情况下获得所需内容的最快方法(默认情况下,我们将编辑很多文件,而增加这些开销毫无意义)。

我们需要编辑的视图是public/res/html/bodyEditor.html –我们将在第44行周围添加一个新的图标容器:

<li><div class="working-indicator"></div></li>
<li><div class="capitalize-button"></div></li>
<li><a class="btn btn-success file-title-navbar" href="#" title="Rename document"> </a></li>

我们在“工作指示器”容器之后添加了一个“大写按钮”容器,因此我们的按钮出现在标题旁边,与标题的上下文最匹配。 不过,这只是容器。

StackEdit UI中的所有按钮都是使用JS构建的。 这发生在文件public/res/libs/Markdown.Editor.js 。 首先,让我们添加按钮标签。 该文件的顶部是defaultStrings数组。 编辑它以包含我们的标题大写标签,如下所示:

[...]
        help: "Markdown Editing Help",
        
        titlecapitalization: "Autocapitalize Title"
    };

然后,向下滚动到同一文件中的makeSpritedButtonRow函数,并在if (helpOptions) {块上方添加以下内容:

buttons.titlecapitalization = makeButton("wmd-titlecapitalization", getString("titlecapitalization"), "-240px", bindCommand(function (chunk, postProcessing) {
                alert("Hello");
            }));

这将创建一个与其余编辑器主题匹配的按钮,并为它提供一个title属性以及我们定义的字符串,因此当我们将鼠标悬停在该按钮上时可以看到它。 单击时还将显示“ Hello”。 但是,它仍然不会显示在界面中。 为此,我们需要编辑public/res/core.js

找到注释// Add customized buttons在该文件中// Add customized buttons ,然后转到该块的末尾。 在此添加以下内容:

$("#wmd-titlecapitalization").append($('<i class="icon-check">')).prependTo($('.capitalize-button'));

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

这将找到我们的按钮容器,并将我们新创建的按钮插入其中。 如果现在以调试模式( homestead.app:5000/editor?debug )刷新编辑器并单击按钮,则应该看到“ Hello”警报,如Markdown.Editor.js的回调所定义。

逻辑

现在已经添加了按钮,让我们按我们想要的去做。

首先,让我们获取标题字段的文本。 编辑Markdown.Editor.js 。 替换alert("Hello"); 在按钮的回调中包含以下内容:

console.log($(".title-container a").text());

现在单击按钮将在控制台中生成当前文档标题。 到目前为止,一切都很好。

为了获得我们想要做什么的逻辑,我们将“借用” TitleCapitalization.com中的代码。 如果您查看源代码,您会发现它位于底部的脚本标记中。 稍微清理一下以删除特定于站点的内容,最终得到以下结果:

(function(){
    var prepositions = [
      'a',
      'abaft',
      'aboard',
      'about',
      'above',
      'absent',
      'across',
      'afore',
      'after',
      'against',
      'along',
      'alongside',
      'amid',
      'amidst',
      'among',
      'amongst',
      'an',
      'apropos',
      'apud',
      'around',
      'as',
      'aside',
      'astride',
      'at',
      'athwart',
      'atop',
      'barring',
      'before',
      'behind',
      'below',
      'beneath',
      'beside',
      'besides',
      'between',
      'beyond',
      'but',
      'by',
      'circa',
      'concerning',
      'despite',
      'down',
      'during',
      'except',
      'excluding',
      'failing',
      'following',
      'for',
      'from',
      'given',
      'in',
      'including',
      'inside',
      'into',
      'lest',
      'like',
      'mid',
      'midst',
      'minus',
      'modulo',
      'near',
      'next',
      'notwithstanding',
      'of',
      'off',
      'on',
      'onto',
      'opposite',
      'out',
      'outside',
      'over',
      'pace',
      'past',
      'per',
      'plus',
      'pro',
      'qua',
      'regarding',
      'round',
      'sans',
      // while it technically can be a preoposition, 
      // (http://www.merriam-webster.com/thesaurus/save[preposition])
      // it is usually used as a verb
      // 'save',
      'since',
      'than',
      'through',
      'thru',
      'throughout',
      'thruout',
      'till',
      'times',
      'to',
      'toward',
      'towards',
      'under',
      'underneath',
      'unlike',
      'until',
      'unto',
      'up',
      'upon',
      'versus',
      'vs\.',
      'vs',
      'v\.',
      'v',
      'via',
      'vice',
      'with',
      'within',
      'without',
      'worth'
    ];
    var articles = [
      'a',
      'an',
      'the'
    ];
    var conjunctions = [
      'and',
      'but',
      'for',
      'so',
      'nor',
      'or',
      'yet'
    ];
    // var small = "(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v[.]?|via|vs[.]?)";
    var punct = "([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]*)";

    var all_lower_case = '(' + (prepositions.concat(articles).concat(conjunctions)).join('|') + ')';
    console.log('all lower case', all_lower_case);
    
    window.titleCaps = function(title){
      var parts = [], split = /[:.;?!] |(?: |^)["Ò]/g, index = 0;

      title = title.replace(/[\u2018\u2019]/g, "'")
        .replace(/[\u201C\u201D]/g, '"');
      
      while (true) {
        var m = split.exec(title);
  
        parts.push( title.substring(index, m ? m.index : title.length)
          .replace(/\b([A-Za-z][a-z.'Õ]*)\b/g, function(all){
            return /[A-Za-z]\.[A-Za-z]/.test(all) ? all : upper(all);
          })
          //.replace(RegExp("\\b" + small + "\\b", "ig"), lower)
          //.replace(RegExp("^" + punct + small + "\\b", "ig"), function(all, punct, word){
          //  return punct + upper(word);
          //})
          //.replace(RegExp("\\b" + small + punct + "$", "ig"), upper));
          .replace(RegExp("\\b" + all_lower_case + "\\b", "ig"), lower)
          .replace(RegExp("^" + punct + all_lower_case + "\\b", "ig"), function(all, punct, word){
            return punct + upper(word);
          })
          .replace(RegExp("\\b" + all_lower_case + punct + "$", "ig"), upper));
        
        index = split.lastIndex;
        
        if ( m ) parts.push( m[0] );
        else break;
      }
      
      return parts.join("").replace(/ V(s?)\. /ig, " v$1. ")
        .replace(/(['Õ])S\b/ig, "$1s")
        .replace(/\b(AT&T|Q&A)\b/ig, function(all){
          return all.toUpperCase();
        });
    };
      
    function lower(word){
      return word.toLowerCase();
    }
      
    function upper(word){
      return word.substr(0,1).toUpperCase() + word.substr(1);
    }
  })();

如果现在将其粘贴到控制台中,则可以访问名为“ titleCaps”的根函数,该根函数接受字符串并打印出标题大写的字符串。 这正是我们所需要的。

再次编辑按钮的回调,并将其更改为:

var titleContainer = $('.title-container a');
var capitalized = capitalize($(titleContainer).text());
$(titleContainer).text(capitalized);
$(".input-file-title").val(capitalized);

现在我们所缺少的只是capitalize功能。 环顾Markdown.Editor.js的代码,我们可以看到泛型函数仍然存在(例如,请参见properlyEncoded的Encoded)。 因此,我们也不需要再考虑将这样的想法纳入考虑范围。 在文件末尾,最后一个})();之前})(); ,添加以下内容:

var prepositions = [
        'a',
        'abaft',
        'aboard',
        'about',
        'above',
        'absent',
        'across',
        'afore',
        'after',
        'against',
        'along',
        'alongside',
        'amid',
        'amidst',
        'among',
        'amongst',
        'an',
        'apropos',
        'apud',
        'around',
        'as',
        'aside',
        'astride',
        'at',
        'athwart',
        'atop',
        'barring',
        'before',
        'behind',
        'below',
        'beneath',
        'beside',
        'besides',
        'between',
        'beyond',
        'but',
        'by',
        'circa',
        'concerning',
        'despite',
        'down',
        'during',
        'except',
        'excluding',
        'failing',
        'following',
        'for',
        'from',
        'given',
        'in',
        'including',
        'inside',
        'into',
        'lest',
        'like',
        'mid',
        'midst',
        'minus',
        'modulo',
        'near',
        'next',
        'notwithstanding',
        'of',
        'off',
        'on',
        'onto',
        'opposite',
        'out',
        'outside',
        'over',
        'pace',
        'past',
        'per',
        'plus',
        'pro',
        'qua',
        'regarding',
        'round',
        'sans',
        'since',
        'than',
        'through',
        'thru',
        'throughout',
        'thruout',
        'till',
        'times',
        'to',
        'toward',
        'towards',
        'under',
        'underneath',
        'unlike',
        'until',
        'unto',
        'up',
        'upon',
        'versus',
        'vs\.',
        'vs',
        'v\.',
        'v',
        'via',
        'vice',
        'with',
        'within',
        'without',
        'worth'
    ];
    var articles = [
        'a',
        'an',
        'the'
    ];
    var conjunctions = [
        'and',
        'but',
        'for',
        'so',
        'nor',
        'or',
        'yet'
    ];
    var punct = "([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]*)";

    var all_lower_case = '(' + (prepositions.concat(articles).concat(conjunctions)).join('|') + ')';
    console.log('all lower case', all_lower_case);

    var capitalize = function(title){
        var parts = [], split = /[:.;?!] |(?: |^)["Ò]/g, index = 0;

        title = title.replace(/[\u2018\u2019]/g, "'")
            .replace(/[\u201C\u201D]/g, '"');

        while (true) {
            var m = split.exec(title);

            parts.push( title.substring(index, m ? m.index : title.length)
                .replace(/\b([A-Za-z][a-z.'Õ]*)\b/g, function(all){
                    return /[A-Za-z]\.[A-Za-z]/.test(all) ? all : upper(all);
                })
                .replace(RegExp("\\b" + all_lower_case + "\\b", "ig"), lower)
                .replace(RegExp("^" + punct + all_lower_case + "\\b", "ig"), function(all, punct, word){
                    return punct + upper(word);
                })
                .replace(RegExp("\\b" + all_lower_case + punct + "$", "ig"), upper));

            index = split.lastIndex;

            if ( m ) parts.push( m[0] );
            else break;
        }

        return parts.join("").replace(/ V(s?)\. /ig, " v$1. ")
            .replace(/(['Õ])S\b/ig, "$1s")
            .replace(/\b(AT&T|Q&A)\b/ig, function(all){
                return all.toUpperCase();
            });
    };

    function lower(word){
        return word.toLowerCase();
    }

    function upper(word){
        return word.substr(0,1).toUpperCase() + word.substr(1);
    }

如果您现在对此进行测试,您会发现“ Hello world”之类的标题被大写为“ Hello World”。 单击标题字段,您会注意到它也适用于内部文本–一切均已正确大写:

01

结论

在本文中,我们首先在本地托管了MarkDown编辑器StackEdit,从而实现了所需的新功能。 我们添加了一个按钮,从TitleCapitalization窃取了功能,并将其回收到我们的环境中。 如果愿意,我们现在可以使用此升级将拉取请求发送给项目所有者。 在您阅读本文时,它可能会被接受,也可能会被拒绝,但是无论如何,我们的本地副本已实现了功能,我们可以按预期使用它。

注释? 反馈? 让我知道!

翻译自: https://www.sitepoint.com/implementing-titlecapitalization-stackedit/

stackedit

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值