因为 MarkDownload - Markdown Web Clipper 插件在 Safari 上无法正常吊起 Obsidian,只好用不太便捷的收藏夹功能来实现网页保存。参考 Github上的讨论和源代码,在 Bookmark Maker 上进行调试,最终在 Safari 浏览器上实现了以 markdown 格式一键剪藏网页内容或选中内容,并按照特定格式保存到 Obsidian 上。

网页剪裁,并创建新的页面

修改书签代码

根据 Obsidian 配置以及剪藏内容格式需求,修改书签代码。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
javascript: Promise.all([import('https://unpkg.com/[email protected]?module'), import('https://unpkg.com/@tehshrike/[email protected]'), ]).then(async ([{
    default: Turndown
}, {
    default: Readability
}]) => {

  /* Optional vault name */
  const vault = "";

  /* Optional folder name such as "Clippings/" */
  const folder = "content/posts/";

  /* Optional tags  */
  let tags = "Reading";

  /* parse and lightly clean the site's meta keywords content into tags, if present */
  if (document.querySelector('meta[name="keywords" i]')) {
      var keywords = document.querySelector('meta[name="keywords" i]').getAttribute('content').split(',');

      keywords.forEach(function(keyword) {
          let tag = ' ' + keyword.split(' ').join('');
          tags += tag;
      });
  }

  function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
  }

  const selection = getSelectionHtml();

  const {
      title,
      byline,
      content
  } = new Readability(document.cloneNode(true)).parse();

  function getFileName(fileName) {
    var userAgent = window.navigator.userAgent,
        platform = window.navigator.platform,
        windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];

    if (windowsPlatforms.indexOf(platform) !== -1) {
      fileName = fileName.replace(':', '').replace(/[/\\?%*|"<>]/g, '-');
    } else {
      fileName = fileName.replace(':', '').replace(/\//g, '-').replace(/\\/g, '-');
    }
    return fileName;
  }
  const fileName = getFileName(title);

  if (selection) {
      var markdownify = selection;
  } else {
      var markdownify = content;
  }

  if (vault) {
      var vaultName = '&vault=' + encodeURIComponent(`${vault}`);
  } else {
      var vaultName = '';
  }

  const markdownBody = new Turndown({
      headingStyle: 'atx',
      hr: '~~~',
      bulletListMarker: '-',
      codeBlockStyle: 'fenced',
      emDelimiter: '*',
  }).turndown(markdownify);

  var date = new Date();

  function convertDate(date) {
    var yyyy = date.getFullYear().toString();
    var mm = (date.getMonth()+1).toString();
    var dd  = date.getDate().toString();
    var mmChars = mm.split('');
    var ddChars = dd.split('');
    return yyyy + '-' + (mmChars[1]?mm:"0"+mmChars[0]) + '-' + (ddChars[1]?dd:"0"+ddChars[0]);
  }

  const today = convertDate(date);

  /* YAML front matter as tags render cleaner with special chars  */
  const fileContent = 
      "---\n"
      // + "author:    " + byline + "\n"
      + "title:     [" + title + "]\n"
      // + "source:    " + document.URL + "\n"
      + "date:   " + today + "\n"
/*      + "published: \n\n"   */
      + "tags:      [" + tags + "]\n"
      + "---\n\n"
      + '>' 
      + markdownBody ;
  
  
  /* add a link to the source at the end */
  const linkref = 
      "\n\n-\n\source: [" + title + "](" + document.URL + ")\n";

  /* assemble URL, decrementing each time, until it does not exceed the max URL length for this browser, supposedly 2048 but allow for a little error with 2030 */
  contentLength = 2048;
  maxURLLength = 2030;
  decrement = 1;

  do {
    hrefString = "obsidian://new?"
      + "file=" + encodeURIComponent(folder + fileName)
      + "&content=" + encodeURIComponent(fileContent.substr(0,contentLength-1)) + encodeURIComponent(linkref) 
      + vaultName ;
    contentLength = contentLength - decrement;
  } while (hrefString.length > maxURLLength);

  document.location.href = hrefString;

})

创建浏览器书签

在 Safari 收藏夹里插件任意书签,然后更改书签地址为以下内容。之后在任意网页上使用该书签即可。

1
javascript:(function()%7Bjavascript%3A%20Promise.all(%5Bimport('https%3A%2F%2Funpkg.com%2Fturndown%406.0.0%3Fmodule')%2C%20import('https%3A%2F%2Funpkg.com%2F%40tehshrike%2Freadability%400.2.0')%2C%20%5D).then(async%20(%5B%7B%0A%20%20%20%20default%3A%20Turndown%0A%7D%2C%20%7B%0A%20%20%20%20default%3A%20Readability%0A%7D%5D)%20%3D%3E%20%7B%0A%0A%20%20%2F*%20Optional%20vault%20name%20*%2F%0A%20%20const%20vault%20%3D%20%22%22%3B%0A%0A%20%20%2F*%20Optional%20folder%20name%20such%20as%20%22Clippings%2F%22%20*%2F%0A%20%20const%20folder%20%3D%20%22content%2Fposts%2F%22%3B%0A%0A%20%20%2F*%20Optional%20tags%20%20*%2F%0A%20%20let%20tags%20%3D%20%22Reading%22%3B%0A%0A%20%20%2F*%20parse%20and%20lightly%20clean%20the%20site's%20meta%20keywords%20content%20into%20tags%2C%20if%20present%20*%2F%0A%20%20if%20(document.querySelector('meta%5Bname%3D%22keywords%22%20i%5D'))%20%7B%0A%20%20%20%20%20%20var%20keywords%20%3D%20document.querySelector('meta%5Bname%3D%22keywords%22%20i%5D').getAttribute('content').split('%2C')%3B%0A%0A%20%20%20%20%20%20keywords.forEach(function(keyword)%20%7B%0A%20%20%20%20%20%20%20%20%20%20let%20tag%20%3D%20'%20'%20%2B%20keyword.split('%20').join('')%3B%0A%20%20%20%20%20%20%20%20%20%20tags%20%2B%3D%20tag%3B%0A%20%20%20%20%20%20%7D)%3B%0A%20%20%7D%0A%0A%20%20function%20getSelectionHtml()%20%7B%0A%20%20%20%20var%20html%20%3D%20%22%22%3B%0A%20%20%20%20if%20(typeof%20window.getSelection%20!%3D%20%22undefined%22)%20%7B%0A%20%20%20%20%20%20%20%20var%20sel%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20if%20(sel.rangeCount)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20container%20%3D%20document.createElement(%22div%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(var%20i%20%3D%200%2C%20len%20%3D%20sel.rangeCount%3B%20i%20%3C%20len%3B%20%2B%2Bi)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20container.appendChild(sel.getRangeAt(i).cloneContents())%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20html%20%3D%20container.innerHTML%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%20else%20if%20(typeof%20document.selection%20!%3D%20%22undefined%22)%20%7B%0A%20%20%20%20%20%20%20%20if%20(document.selection.type%20%3D%3D%20%22Text%22)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20html%20%3D%20document.selection.createRange().htmlText%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20return%20html%3B%0A%20%20%7D%0A%0A%20%20const%20selection%20%3D%20getSelectionHtml()%3B%0A%0A%20%20const%20%7B%0A%20%20%20%20%20%20title%2C%0A%20%20%20%20%20%20byline%2C%0A%20%20%20%20%20%20content%0A%20%20%7D%20%3D%20new%20Readability(document.cloneNode(true)).parse()%3B%0A%0A%20%20function%20getFileName(fileName)%20%7B%0A%20%20%20%20var%20userAgent%20%3D%20window.navigator.userAgent%2C%0A%20%20%20%20%20%20%20%20platform%20%3D%20window.navigator.platform%2C%0A%20%20%20%20%20%20%20%20windowsPlatforms%20%3D%20%5B'Win32'%2C%20'Win64'%2C%20'Windows'%2C%20'WinCE'%5D%3B%0A%0A%20%20%20%20if%20(windowsPlatforms.indexOf(platform)%20!%3D%3D%20-1)%20%7B%0A%20%20%20%20%20%20fileName%20%3D%20fileName.replace('%3A'%2C%20'').replace(%2F%5B%2F%5C%5C%3F%25*%7C%22%3C%3E%5D%2Fg%2C%20'-')%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20fileName%20%3D%20fileName.replace('%3A'%2C%20'').replace(%2F%5C%2F%2Fg%2C%20'-').replace(%2F%5C%5C%2Fg%2C%20'-')%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20fileName%3B%0A%20%20%7D%0A%20%20const%20fileName%20%3D%20getFileName(title)%3B%0A%0A%20%20if%20(selection)%20%7B%0A%20%20%20%20%20%20var%20markdownify%20%3D%20selection%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20var%20markdownify%20%3D%20content%3B%0A%20%20%7D%0A%0A%20%20if%20(vault)%20%7B%0A%20%20%20%20%20%20var%20vaultName%20%3D%20'%26vault%3D'%20%2B%20encodeURIComponent(%60%24%7Bvault%7D%60)%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20var%20vaultName%20%3D%20''%3B%0A%20%20%7D%0A%0A%20%20const%20markdownBody%20%3D%20new%20Turndown(%7B%0A%20%20%20%20%20%20headingStyle%3A%20'atx'%2C%0A%20%20%20%20%20%20hr%3A%20'~~~'%2C%0A%20%20%20%20%20%20bulletListMarker%3A%20'-'%2C%0A%20%20%20%20%20%20codeBlockStyle%3A%20'fenced'%2C%0A%20%20%20%20%20%20emDelimiter%3A%20'*'%2C%0A%20%20%7D).turndown(markdownify)%3B%0A%0A%20%20var%20date%20%3D%20new%20Date()%3B%0A%0A%20%20function%20convertDate(date)%20%7B%0A%20%20%20%20var%20yyyy%20%3D%20date.getFullYear().toString()%3B%0A%20%20%20%20var%20mm%20%3D%20(date.getMonth()%2B1).toString()%3B%0A%20%20%20%20var%20dd%20%20%3D%20date.getDate().toString()%3B%0A%20%20%20%20var%20mmChars%20%3D%20mm.split('')%3B%0A%20%20%20%20var%20ddChars%20%3D%20dd.split('')%3B%0A%20%20%20%20return%20yyyy%20%2B%20'-'%20%2B%20(mmChars%5B1%5D%3Fmm%3A%220%22%2BmmChars%5B0%5D)%20%2B%20'-'%20%2B%20(ddChars%5B1%5D%3Fdd%3A%220%22%2BddChars%5B0%5D)%3B%0A%20%20%7D%0A%0A%20%20const%20today%20%3D%20convertDate(date)%3B%0A%0A%20%20%2F*%20YAML%20front%20matter%20as%20tags%20render%20cleaner%20with%20special%20chars%20%20*%2F%0A%20%20const%20fileContent%20%3D%20%0A%20%20%20%20%20%20%22---%5Cn%22%0A%20%20%20%20%20%20%2F%2F%20%2B%20%22author%3A%20%20%20%20%22%20%2B%20byline%20%2B%20%22%5Cn%22%0A%20%20%20%20%20%20%2B%20%22title%3A%20%20%20%20%20%5B%22%20%2B%20title%20%2B%20%22%5D%5Cn%22%0A%20%20%20%20%20%20%2F%2F%20%2B%20%22source%3A%20%20%20%20%22%20%2B%20document.URL%20%2B%20%22%5Cn%22%0A%20%20%20%20%20%20%2B%20%22date%3A%20%20%20%22%20%2B%20today%20%2B%20%22%5Cn%22%0A%2F*%20%20%20%20%20%20%2B%20%22published%3A%20%5Cn%5Cn%22%20%20%20*%2F%0A%20%20%20%20%20%20%2B%20%22tags%3A%20%20%20%20%20%20%5B%22%20%2B%20tags%20%2B%20%22%5D%5Cn%22%0A%20%20%20%20%20%20%2B%20%22---%5Cn%5Cn%22%0A%20%20%20%20%20%20%2B%20'%3E'%20%0A%20%20%20%20%20%20%2B%20markdownBody%20%3B%0A%20%20%0A%20%20%0A%20%20%2F*%20add%20a%20link%20to%20the%20source%20at%20the%20end%20*%2F%0A%20%20const%20linkref%20%3D%20%0A%20%20%20%20%20%20%22%5Cn%5Cn-%5Cn%5Csource%3A%20%5B%22%20%2B%20title%20%2B%20%22%5D(%22%20%2B%20document.URL%20%2B%20%22)%5Cn%22%3B%0A%0A%20%20%2F*%20assemble%20URL%2C%20decrementing%20each%20time%2C%20until%20it%20does%20not%20exceed%20the%20max%20URL%20length%20for%20this%20browser%2C%20supposedly%202048%20but%20allow%20for%20a%20little%20error%20with%202030%20*%2F%0A%20%20contentLength%20%3D%202048%3B%0A%20%20maxURLLength%20%3D%202030%3B%0A%20%20decrement%20%3D%201%3B%0A%0A%20%20do%20%7B%0A%20%20%20%20hrefString%20%3D%20%22obsidian%3A%2F%2Fnew%3F%22%0A%20%20%20%20%20%20%2B%20%22file%3D%22%20%2B%20encodeURIComponent(folder%20%2B%20fileName)%0A%20%20%20%20%20%20%2B%20%22%26content%3D%22%20%2B%20encodeURIComponent(fileContent.substr(0%2CcontentLength-1))%20%2B%20encodeURIComponent(linkref)%20%0A%20%20%20%20%20%20%2B%20vaultName%20%3B%0A%20%20%20%20contentLength%20%3D%20contentLength%20-%20decrement%3B%0A%20%20%7D%20while%20(hrefString.length%20%3E%20maxURLLength)%3B%0A%0A%20%20document.location.href%20%3D%20hrefString%3B%0A%0A%7D)%7D)()%3B

或者,直接使用 Obsidian 书签制作器

如果对剪藏格式没有特殊要求的话,可以直接使用 Obsidian Clipper Maker 快速制作书签。

网页剪裁,追加到日历内容

基于上面的代码修改,该书签不创建新页面,直接将文摘和链接添加到当天日历内容里。

书签

1
javascript:(function()%7Bjavascript%3A%20Promise.all(%5Bimport('https%3A%2F%2Funpkg.com%2Fturndown%406.0.0%3Fmodule')%2C%20import('https%3A%2F%2Funpkg.com%2F%40tehshrike%2Freadability%400.2.0')%2C%20%5D).then(async%20(%5B%7B%0A%20%20%20%20default%3A%20Turndown%0A%7D%2C%20%7B%0A%20%20%20%20default%3A%20Readability%0A%7D%5D)%20%3D%3E%20%7B%0A%0A%20%20function%20getSelectionHtml()%20%7B%0A%20%20%20%20var%20html%20%3D%20%22%22%3B%0A%20%20%20%20if%20(typeof%20window.getSelection%20!%3D%20%22undefined%22)%20%7B%0A%20%20%20%20%20%20%20%20var%20sel%20%3D%20window.getSelection()%3B%0A%20%20%20%20%20%20%20%20if%20(sel.rangeCount)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20var%20container%20%3D%20document.createElement(%22div%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20(var%20i%20%3D%200%2C%20len%20%3D%20sel.rangeCount%3B%20i%20%3C%20len%3B%20%2B%2Bi)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20container.appendChild(sel.getRangeAt(i).cloneContents())%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20html%20%3D%20container.innerHTML%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%20else%20if%20(typeof%20document.selection%20!%3D%20%22undefined%22)%20%7B%0A%20%20%20%20%20%20%20%20if%20(document.selection.type%20%3D%3D%20%22Text%22)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20html%20%3D%20document.selection.createRange().htmlText%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20return%20html%3B%0A%20%20%7D%0A%0A%20%20const%20selection%20%3D%20getSelectionHtml()%3B%0A%0A%20%20const%20%7B%0A%20%20%20%20%20%20title%2C%0A%20%20%20%20%20%20content%0A%20%20%7D%20%3D%20new%20Readability(document.cloneNode(true)).parse()%3B%0A%0A%20%20function%20getFileName(fileName)%20%7B%0A%20%20%20%20var%20userAgent%20%3D%20window.navigator.userAgent%2C%0A%20%20%20%20%20%20%20%20platform%20%3D%20window.navigator.platform%2C%0A%20%20%20%20%20%20%20%20windowsPlatforms%20%3D%20%5B'Win32'%2C%20'Win64'%2C%20'Windows'%2C%20'WinCE'%5D%3B%0A%0A%20%20%20%20if%20(windowsPlatforms.indexOf(platform)%20!%3D%3D%20-1)%20%7B%0A%20%20%20%20%20%20fileName%20%3D%20fileName.replace('%3A'%2C%20'').replace(%2F%5B%2F%5C%5C%3F%25*%7C%22%3C%3E%5D%2Fg%2C%20'-')%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20fileName%20%3D%20fileName.replace('%3A'%2C%20'').replace(%2F%5C%2F%2Fg%2C%20'-').replace(%2F%5C%5C%2Fg%2C%20'-')%3B%0A%20%20%20%20%7D%0A%20%20%20%20return%20fileName%3B%0A%20%20%7D%0A%20%20const%20fileName%20%3D%20getFileName(title)%3B%0A%0A%20%20if%20(selection)%20%7B%0A%20%20%20%20%20%20var%20markdownify%20%3D%20selection%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20var%20markdownify%20%3D%20content%3B%0A%20%20%7D%0A%0A%20%20const%20markdownBody%20%3D%20new%20Turndown(%7B%0A%20%20%20%20%20%20headingStyle%3A%20'atx'%2C%0A%20%20%20%20%20%20hr%3A%20'~~~'%2C%0A%20%20%20%20%20%20bulletListMarker%3A%20'-'%2C%0A%20%20%20%20%20%20codeBlockStyle%3A%20'fenced'%2C%0A%20%20%20%20%20%20emDelimiter%3A%20'*'%2C%0A%20%20%7D).turndown(markdownify)%3B%0A%0A%20%20const%20fileContent%20%3D%20%0A%20%20%20%20%20%20'-%20'%20%0A%20%20%20%20%20%20%2B%20markdownBody%20%3B%0A%20%20%0A%20%20%0A%20%20%2F*%20add%20a%20link%20to%20the%20source%20at%20the%20end%20*%2F%0A%20%20const%20linkref%20%3D%20%0A%20%20%20%20%20%20%22%5Cn%5C%20%20%20%20%5B%22%20%2B%20title%20%2B%20%22%5D(%22%20%2B%20document.URL%20%2B%20%22)%5Cn%22%3B%0A%0A%20%20%2F*%20assemble%20URL%2C%20decrementing%20each%20time%2C%20until%20it%20does%20not%20exceed%20the%20max%20URL%20length%20for%20this%20browser%2C%20supposedly%202048%20but%20allow%20for%20a%20little%20error%20with%202030%20*%2F%0A%20%20contentLength%20%3D%202048%3B%0A%20%20maxURLLength%20%3D%202030%3B%0A%20%20decrement%20%3D%201%3B%0A%0A%20%20do%20%7B%0A%20%20%20%20hrefString%20%3D%20%22obsidian%3A%2F%2Fadvanced-uri%3F%22%0A%20%20%20%20%20%20%2B%20%22file%3D%22%20%2B%20encodeURIComponent(fileName)%0A%20%20%20%20%20%20%2B%20%22%26daily%3Dtrue%26heading%3DClippings%26mode%3Dappend%26data%3D%22%20%2B%20encodeURIComponent(fileContent.substr(0%2CcontentLength-1))%20%2B%20encodeURIComponent(linkref)%20%3B%0A%20%20%20%20contentLength%20%3D%20contentLength%20-%20decrement%3B%0A%20%20%7D%20while%20(hrefString.length%20%3E%20maxURLLength)%3B%0A%0A%20%20document.location.href%20%3D%20hrefString%3B%0A%0A%7D)%7D)()%3B

书签代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
javascript: Promise.all([import('https://unpkg.com/[email protected]?module'), import('https://unpkg.com/@tehshrike/[email protected]'), ]).then(async ([{
    default: Turndown
}, {
    default: Readability
}]) => {

  function getSelectionHtml() {
    var html = "";
    if (typeof window.getSelection != "undefined") {
        var sel = window.getSelection();
        if (sel.rangeCount) {
            var container = document.createElement("div");
            for (var i = 0, len = sel.rangeCount; i < len; ++i) {
                container.appendChild(sel.getRangeAt(i).cloneContents());
            }
            html = container.innerHTML;
        }
    } else if (typeof document.selection != "undefined") {
        if (document.selection.type == "Text") {
            html = document.selection.createRange().htmlText;
        }
    }
    return html;
  }

  const selection = getSelectionHtml();

  const {
      title,
      content
  } = new Readability(document.cloneNode(true)).parse();

  function getFileName(fileName) {
    var userAgent = window.navigator.userAgent,
        platform = window.navigator.platform,
        windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];

    if (windowsPlatforms.indexOf(platform) !== -1) {
      fileName = fileName.replace(':', '').replace(/[/\\?%*|"<>]/g, '-');
    } else {
      fileName = fileName.replace(':', '').replace(/\//g, '-').replace(/\\/g, '-');
    }
    return fileName;
  }
  const fileName = getFileName(title);

  if (selection) {
      var markdownify = selection;
  } else {
      var markdownify = content;
  }

  const markdownBody = new Turndown({
      headingStyle: 'atx',
      hr: '~~~',
      bulletListMarker: '-',
      codeBlockStyle: 'fenced',
      emDelimiter: '*',
  }).turndown(markdownify);

  const fileContent = 
      '- ' 
      + markdownBody ;
  
  
  /* add a link to the source at the end */
  const linkref = 
      "\n\    [" + title + "](" + document.URL + ")\n";

  /* assemble URL, decrementing each time, until it does not exceed the max URL length for this browser, supposedly 2048 but allow for a little error with 2030 */
  contentLength = 2048;
  maxURLLength = 2030;
  decrement = 1;

  do {
    hrefString = "obsidian://advanced-uri?"
      + "file=" + encodeURIComponent(fileName)
      + "&daily=true&heading=Clippings&mode=append&data=" + encodeURIComponent(fileContent.substr(0,contentLength-1)) + encodeURIComponent(linkref) ;
    contentLength = contentLength - decrement;
  } while (hrefString.length > maxURLLength);

  document.location.href = hrefString;

})

优化时间代码

1
2
 new Date().toLocaleString();
const today = new Date().toLocaleString('en-GB');

ChatGPT 优化版本

使用 ChatGPT 做了一些优化调整(不确定是不是真的优化了,哈哈),同时去除了文摘字数的限制,能够全文保存了。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
(() => {
   const contentLength = Infinity; // Set an appropriate length limit for the content 2048

  // Fetch required libraries
  const fetchLibraries = async () => {
    const [Turndown, Readability] = await Promise.all([
      import('https://unpkg.com/[email protected]?module'),
      import('https://unpkg.com/@tehshrike/[email protected]'),
    ]);

    return { Turndown: Turndown.default, Readability: Readability.default };
  };

  // Get HTML content of the selected text
  const getSelectionHtml = () => {
    var html = "";
    if (typeof window.getSelection != "undefined") {
      var sel = window.getSelection();
      if (sel.rangeCount) {
        var container = document.createElement("div");
        for (var i = 0, len = sel.rangeCount; i < len; ++i) {
          container.appendChild(sel.getRangeAt(i).cloneContents());
        }
        html = container.innerHTML;
      }
    } else if (typeof document.selection != "undefined") {
      if (document.selection.type == "Text") {
        html = document.selection.createRange().htmlText;
      }
    }
    return html;
  };

  // Generate a safe file name
  const getFileName = (fileName) => {
    var userAgent = window.navigator.userAgent,
      platform = window.navigator.platform,
      windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];

    if (windowsPlatforms.indexOf(platform) !== -1) {
      fileName = fileName.replace(':', '').replace(/[/\\?%*|"<>]/g, '-');
    } else {
      fileName = fileName.replace(':', '').replace(/\//g, '-').replace(/\\/g, '-');
    }
    return fileName;
  };

  // Get meta content by attribute and value
  const getMetaContent = (attr, value) => {
    var element = document.querySelector(`meta[${attr}='${value}']`);
    return element ? element.getAttribute("content").trim() : "";
  };

  // Format author information
  const formatAuthor = (byline) => {
    var author = byline || getMetaContent("name", "author") || getMetaContent("property", "author") || getMetaContent("property", "og:site_name");
    return author ? `"[[${author}]]"` : "";
  };

// Format the date and time string as YYYY-MM-DDTHH:mm:ss
const formatDateString = (date) => {
  const options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', timeZoneName: 'short' };
  return date.toISOString('en-US', options).replace(/,/g, ''); // Remove comma in the time zone
};



  // Markdownify the captured content
  const markdownifyContent = (content, Turndown) => {
    return new Turndown({
      headingStyle: 'atx',
      hr: '~~~',
      bulletListMarker: '-',
      codeBlockStyle: 'fenced',
      emDelimiter: '*',
    }).turndown(content);
  };

  // Generate markdown content
  const generateMarkdown = ({ title, byline, content, tags, url, formattedDate, author, Turndown }) => {
    const markdownBody = markdownifyContent(content, Turndown);
    return `---\n`
      + `type: linklog\n`
      + `title: ${title}\n`
      + `source: ${url}\n`
      + `date: ${formattedDate}\n`
      + `tags: [${tags}]\n`
      + `---\n\n`
      + `${markdownBody}`;
  };

  // Generate Obsidian link
  const generateObsidianLink = ({ folder, fileName, content }) => {
    return `obsidian://new?`
      + `file=${encodeURIComponent(folder + fileName)}`
      + `&content=${encodeURIComponent(content)}`;
  };

  // Main function
  fetchLibraries().then(async ({ Turndown, Readability }) => {
    const vault = ''; // Optional vault name
    const folder = 'content/linklog/'; // Optional folder name
    let tags = 'Reading'; // Optional tags

    const selection = getSelectionHtml();
    const { title, byline, content } = new Readability(document.cloneNode(true)).parse();
    const fileName = getFileName(title);

    const today = new Date();
    const formattedDate = formatDateString(today);
    const author = formatAuthor(byline);

    const fileContent = generateMarkdown({ title, byline, content, tags, url: document.URL, formattedDate, author, Turndown });

    const linkref = `\n\n-\n\source: [${title}](${document.URL})\n`;

    const obsidianLink = generateObsidianLink({ folder, fileName, content: `${fileContent}${linkref}` });

    document.location.href = obsidianLink;
  });
})();