diff --git a/_config.yml b/_config.yml
index 2b877c3acb4d..a1cdb90f5f82 100644
--- a/_config.yml
+++ b/_config.yml
@@ -136,4 +136,3 @@ alias:
tags/GCP/: tags/GoogleCloud/
tags/画像認識/: tags/画像処理/
tags/icon: categories/アイコン/
-
diff --git a/package-lock.json b/package-lock.json
index 65ef4a96e2bf..8182b837e674 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"name": "future-tech-blog",
"version": "0.1.0",
"dependencies": {
+ "cheerio": "^1.1.2",
"googleapis": "^126.0.1",
"hexo": "^7.2.0",
"hexo-easy-tags-plugin": "^1.1.0",
@@ -31,6 +32,7 @@
"image-size": "^1.0.2",
"js-yaml": "^4.1.0",
"markdown-it": "^14.1.0",
+ "node-fetch": "^2.7.0",
"npm": "^10.1.0",
"random-seed": "^0.3.0",
"rss-parser": "^3.13.0",
@@ -1037,6 +1039,12 @@
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
},
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "license": "ISC"
+ },
"node_modules/boundary": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/boundary/-/boundary-1.0.1.tgz",
@@ -1194,6 +1202,198 @@
"integrity": "sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==",
"dev": true
},
+ "node_modules/cheerio": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.1.2.tgz",
+ "integrity": "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==",
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "encoding-sniffer": "^0.2.1",
+ "htmlparser2": "^10.0.0",
+ "parse5": "^7.3.0",
+ "parse5-htmlparser2-tree-adapter": "^7.1.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^7.12.0",
+ "whatwg-mimetype": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.18.1"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/htmlparser2": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz",
+ "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.1",
+ "entities": "^6.0.0"
+ }
+ },
+ "node_modules/cheerio/node_modules/htmlparser2/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/cheerio/node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@@ -1505,6 +1705,89 @@
"node": "*"
}
},
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-select/node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/css-select/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/css-select/node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/css-select/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
"node_modules/cssom": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
@@ -1776,6 +2059,31 @@
"node": ">= 0.8"
}
},
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
+ "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+ }
+ },
+ "node_modules/encoding-sniffer/node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/entities": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
@@ -4985,6 +5293,7 @@
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -8125,6 +8434,18 @@
"inBundle": true,
"license": "ISC"
},
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
"node_modules/nunjucks": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz",
@@ -8308,20 +8629,62 @@
}
},
"node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "^5.0.3",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/parse5-parser-stream": {
"version": "7.1.2",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
- "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "license": "MIT",
"dependencies": {
- "entities": "^4.4.0"
+ "parse5": "^7.0.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parse5/node_modules/entities": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
- "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
@@ -10921,6 +11284,15 @@
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
"license": "MIT"
},
+ "node_modules/undici": {
+ "version": "7.16.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz",
+ "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.18.1"
+ }
+ },
"node_modules/unicorn-magic": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
diff --git a/package.json b/package.json
index a3b4728e2dc4..4538cb85bcdc 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"version": "7.2.0"
},
"dependencies": {
+ "cheerio": "^1.1.2",
"googleapis": "^126.0.1",
"hexo": "^7.2.0",
"hexo-easy-tags-plugin": "^1.1.0",
@@ -29,6 +30,7 @@
"image-size": "^1.0.2",
"js-yaml": "^4.1.0",
"markdown-it": "^14.1.0",
+ "node-fetch": "^2.7.0",
"npm": "^10.1.0",
"random-seed": "^0.3.0",
"rss-parser": "^3.13.0",
@@ -49,4 +51,4 @@
"lint": {
"terraform_guidelines.md": "textlint"
}
-}
\ No newline at end of file
+}
diff --git a/scripts/autolink_image_source.js b/scripts/autolink_image_source.js
new file mode 100644
index 000000000000..8d723a7bb3fd
--- /dev/null
+++ b/scripts/autolink_image_source.js
@@ -0,0 +1,30 @@
+/**
+ * タグの直後にある「出典:URL...」形式のテキストを、複数のURLに対応して自動でリンク化するフィルター
+ */
+hexo.extend.filter.register('after_post_render', function(data) {
+ // 投稿の本文(data.content)に対して処理を行う
+ if (!data || !data.content) {
+ return;
+ }
+
+ //
タグ、間のテキスト、「出典:」、そしてその後のURL群を含むテキスト、というパターンを探す正規表現
+ // [^<]+ は、次のHTMLタグが現れるまでの全てのテキストをキャプチャする
+ const blockRegex = /(
]+>)([\s\S]*?出典:)([^<]+)/g;
+
+ data.content = data.content.replace(blockRegex, (match, imgTag, sourcePrefix, urlsText) => {
+
+ // キャプチャしたURL群のテキスト (urlsText) の中から、個々のURLを探すための正規表現
+ const urlRegex = /(https?:\/\/[^\s<]+)/g;
+
+ // 見つかった全てのURLをタグで囲むように置換する
+ // urlパラメータにはマッチした個々のURL文字列が入る
+ const linkedUrls = urlsText.trim().replace(urlRegex, (url) => {
+ return `${url}`;
+ });
+
+ // 元の
タグ + 「出典:」までのテキスト + リンク化されたURL群 を結合して返す
+ return imgTag + sourcePrefix + ' ' + linkedUrls;
+ });
+
+ return data;
+});
diff --git a/scripts/preview.js b/scripts/preview.js
new file mode 100644
index 000000000000..89f4cd5d2cb2
--- /dev/null
+++ b/scripts/preview.js
@@ -0,0 +1,76 @@
+const fetch = require('node-fetch');
+const cheerio = require('cheerio');
+
+async function getOgpData(url) {
+ try {
+ const response = await fetch(url, {
+ headers: {
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36'
+ }
+ });
+ if (!response.ok) {
+ throw new Error(`Failed to fetch: ${response.statusText}`);
+ }
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const getMetaContent = (prop) => $(`meta[property="${prop}"]`).attr('content') || $(`meta[name="${prop}"]`).attr('content');
+
+ let description = getMetaContent('og:description') || getMetaContent('description');
+ if (description === 'NULL') {
+ description = '';
+ }
+
+ const ogp = {
+ title: getMetaContent('og:title') || $('title').text(),
+ description: description, // 取得したdescriptionを設定
+ image: getMetaContent('og:image'),
+ siteName: getMetaContent('og:site_name'),
+ favicon: $('link[rel="icon"], link[rel="shortcut icon"]').attr('href')
+ };
+
+ if (ogp.favicon && !ogp.favicon.startsWith('http')) {
+ const urlObj = new URL(url);
+ ogp.favicon = `${urlObj.protocol}//${urlObj.hostname}${ogp.favicon}`;
+ }
+
+ return ogp;
+ } catch (error) {
+ console.error(`Error fetching OGP data for ${url}:`, error);
+ return null;
+ }
+}
+
+hexo.extend.tag.register('link_preview', async function(args) {
+ const url = args[0];
+ if (!url) return '';
+
+ const data = await getOgpData(url);
+
+ if (!data || !data.title) {
+ return `${url}`;
+ }
+
+ // 出力時に必ず空文字をフォールバックにする
+ const title = data.title || '';
+ const description = data.description || '';
+ const image = data.image;
+ const siteName = data.siteName || new URL(url).hostname;
+ const favicon = data.favicon;
+
+ return `
+
+
+- [ASUS Zenbook DUO (2024)](https://www.g-mark.org/gallery/winners/23827)
+- [ゲルソノマ 15-50/1201A727](https://www.g-mark.org/gallery/winners/24475?years=2024)
+- [CMF by Nothing Product Range](https://www.g-mark.org/gallery/winners/23510)
+- [ざる屋の盆ざる](https://www.g-mark.org/gallery/winners/27448)
+- [福岡市認知症の人にもやさしいデザイン](https://www.g-mark.org/gallery/winners/25503)
+- [デジロー (デジタル スシロービジョン)](https://www.g-mark.org/gallery/winners/22821?years=2024)
+
+## 時代と共に変化する「良いデザイン」の基準
+
+グッドデザイン賞の審査基準は、時代の変化に伴って変化し続けてきました。
+各時代における「良いデザイン」の変遷をご紹介します。
+
+### 1960年代
+
+高度経済成長期。1964年の東京オリンピック開催に伴い、街中にはピクトグラムが設置され「デザイン」という言葉が浸透し始めた時代。「美的感覚」「独創性」などが重視されました。1960年代中盤のいざなぎ景気時代には、新三種の神器と呼ばれる車、エアコン、カラーテレビなどが広く普及し、経済大国へと成長していきました。
+
+{% link_preview https://www.g-mark.org/gallery/winners/9d03dfe8-803d-11ed-862b-0242ac130002 %}
+
+### 1970-80年代
+
+大阪万博を皮切りに日本の「ものづくり」が世界的に評価された時代。ソニーからは1979年にウォークマン、本田技研工業からは1981年にシティなど、世界に対して発信力の高い製品が数多く登場するようになりました。デザインに「品質水準」「機能性」「安全性」といった尺度が加わりました。
+
+{% link_preview https://www.g-mark.org/gallery/winners/9c6b0333-803d-11ed-862b-0242ac130002 %}
+
+### 1990年代
+
+インターネットが普及し価値が多様化した時代。またスーパーファミコンや、プリクラ、4足歩行ロボット「AIBO」など電子機器が生活になくてはならないものとなり、価値変化の時代となりました。「生活者」や「ライフスタイル」がデザインで重要視される要素になりました。
+
+{% link_preview https://www.g-mark.org/gallery/winners/9cf81f93-803d-11ed-862b-0242ac130002 %}
+
+### 2000年代
+
+「持続可能な開発に関する世界首脳会議(WSSD)」が開催され、地球温暖化などエコ問題が意識され始めた時代。社会課題が顕在化し、「エコロジーデザイン」や「ユニバーサルデザイン」など、社会的な視点が強まりました。トヨタのプリウスは、高性能な新世代ハイブリッドシステムにより世界最高レベルとなる低燃費、低エミッションを追求し、環境性能という新たな価値を生み出しました。
+
+{% link_preview https://www.g-mark.org/gallery/winners/9d19150c-803d-11ed-862b-0242ac130002 %}
+
+### 2010年代
+
+2011年に発生した東日本大震災をきっかけに、防災、地域社会への意識の高まりなど、さまざまな変化が見られた時代。また国内のインターネットの利用者は1億人を超え、音声認識AIの開発や、キャッシュレスの浸透、ドローンなど新しい技術が登場しました。「社会参加」や「創発」が重要なテーマとなりました。
+
+{% link_preview https://www.g-mark.org/gallery/winners/9ddfe3a3-803d-11ed-af7e-0242ac130002 %}
+
+### 2020年代
+
+新型コロナウイルス感染症(COVID-19)の世界的流行により、マスクの着用、ソーシャルディスタンス、また職場や学校などあらゆる場所でオンライン環境が取り入れられるなど「新しい生活様式」が実践されました。また、SDGsの浸透により「持続可能性」のあるデザインが求められるようになりました。
+
+{% link_preview https://www.g-mark.org/gallery/winners/9e389033-803d-11ed-af7e-0242ac130002 %}
+
+出典:https://www.g-mark.org/learn/gda/statistics/screening-criteria
+
+そして2024年時点では、以下の4つの視点から総合的に審査が行われています。
+
+> #### 👤 人間的視点
+>
+> - 使いやすさ・分かりやすさ・親切さなど、ユーザーに対してしかるべき配慮が行われているか
+> - 安全・安心・環境・身体的弱者など、信頼性を確保するための様々な配慮が行われているか
+> - ユーザーから共感を得るデザインであるか
+> - 魅力を有し、ユーザーの創造性を誘発するデザインであるか
+>
+> #### 🏭 産業的視点
+>
+> - 新技術・新素材などを利用または創意工夫によりたくみに課題を解決しているか
+> - 的確な技術・方法・品質で合理的に設計・計画されているか
+> - 新産業、新ビジネスの創出に貢献しているか
+>
+> #### 🌱 社会的視点
+>
+> - 新しい作法、ライフスタイル、コミュニケーションなど、新たな文化の創出に貢献しているか
+> - 持続可能な社会の実現に対して貢献しているか
+> - 新たな手法、概念、様式など、社会に対して新たな価値を提案しているか
+>
+> #### ⏳ 時間的視点
+>
+> - 過去の文脈や蓄積を活かし、新たな価値を提案しているか
+> - 中・長期的な観点から持続可能性の高い提案が行われているか
+> - 時代に即した改善を継続しているか
+>
+>出典:https://www.g-mark.org/apply/gda/screening/perspective
+
+## 受賞事例から見る「良いデザイン」のカタチ
+
+では、具体的にどのようなものが受賞しているのでしょうか。個人的にいいなと感じた3つの事例をご紹介します。
+
+### 1. スマートフォンアプリ - みみみ
+
+https://www.g-mark.org/gallery/winners/26906
+
+「みみみ」はデジタル世代の興味・関心に合わせて地域ニュースを届け、理解を深める体験を提供するアプリです。 デジタル世代の普段使いに馴染む洗練されたデザイン性、スムーズに使えるインターフェースで操作も簡単。
+スワイプしながら手軽にニュースを追える「コレだけ」機能や、浮かんだ疑問を記者に直接質問できる「イドバタ」機能が特徴で、一方的な情報提供ではない、地域に根付いた新聞社ならではの新しいニュース体験の形を示しています。
+
+#### 直感的なニュース体験
+
+デジタル世代の普段使いに馴染む洗練されたデザイン性、スムーズに使えるインターフェースで操作も簡単。ストレスフリーでニュース体験を楽しめます。
+
+
+出典: https://tarupo.jp/mimimi
+
+#### 記者が「?」にこたえる!
+
+話題やコメントが投稿できる「イドバタ」機能。同じ街に住む記者が、身の回りのニュースについて答え、一緒に考えてくれることも。
+
+
+出典:https://tarupo.jp/mimimi
+
+
+
+ちなみに、「みみみ」のユーザ基盤を支えている「たるポ」はFutureとも関わりがあります🎉
+
+- [たるポ このまち応援プラットフォーム](https://tarupo.jp/)
+- [中国新聞社、フューチャーアーキテクトとともに中国地方の地域活性化を推進](https://prtimes.jp/main/html/rd/p/000000012.000105470.html)
+
+### 2. 旅行サービス - どこかにビューーン!
+
+https://www.g-mark.org/gallery/winners/17585
+
+JRE POINT 6,000ポイントで、JR東日本が管轄する47駅の中からランダムに選ばれた「どこか」に行けるサービスです。
+ユーザはお得に新幹線に乗れる、事業者にとっては空席をうまく活用できる、地域にとっては観光資源を知ってもらえる機会が生まれる、という三方よしのサービス。行き先をランダムで選べるワクワク感も楽しいですね。
+
+#### 観光流動の均等化
+
+観光は特定の地域に人気が集中することも多い。そのような中、新幹線の空席状況に合わせて、行き先を決定することで観光流動の均等化に繋げられます。
+
+
+
+
+
+#### 公共サービスの標準化へ
+
+カラーパレット、文字の形状やサイズ、イラストやボタン、コンポーネントなどを国際的に推奨されるガイドラインに基づいて整備。マイナンバーの手続きアプリなどで導入されている。
+公共サービスの標準化が進み、誰もが安心してアクセスできる「優しいデジタル社会」の実現が期待されます。
+
+
+出典:https://design.digital.go.jp/ , https://digital-gov.note.jp/n/n81e591f9c7e7
+
+#### 豊富なガイドラインとコードスニペット
+
+あらかじめアクセシビリティを十分に考慮し、かつデザイン性に優れたデザインライブラリやガイドラインを整備。様々な行政サービスで利用できるようにネット上で公開されています。(動作環境:Webサイト、Figma、GitHub)
+
+
+