AtCoder Submission Language Detector

Automatically detects the language used based on the information in the source code comments and selects it as the one to be submitted.

2022/07/26のページです。最新版はこちら

作者のサイトでサポートを受ける。または、このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
  1. // ==UserScript==
  2. // @name AtCoder Submission Language Detector
  3. // @namespace https://twitter.com/KakurenboUni
  4. // @version 1.0.0
  5. // @description Automatically detects the language used based on the information in the source code comments and selects it as the one to be submitted.
  6. // @author uni-kakurenbo
  7. // @match https://atcoder.jp/contests/*/tasks/*
  8. // @match https://atcoder.jp/contests/*/submit*
  9. // @license MIT
  10. // @supportURL https://twitter.com/KakurenboUni
  11. // ==/UserScript==
  12.  
  13. (async function () {
  14. "use strict";
  15.  
  16. const DETECTION_REG_EXP = /#.*lang(?:uage)?:?(?<args>\s+[^\n\r*/#]+)/;
  17.  
  18. await rendered();
  19.  
  20. const $editor = $(".editor").data("editor").doc;
  21. const $plainTextarea = $(".plain-textarea");
  22.  
  23. const $selectLanguage = $("#select-lang select");
  24. const $languageOptions = $selectLanguage[0].querySelectorAll("option");
  25. const languageOptions = [].map.call($languageOptions, ({ value, label, dataset: { mime } = {} }) => {
  26. return {
  27. id: value,
  28. label: label.toLowerCase() ?? "",
  29. code: mime?.toLowerCase().replaceAll(/^.+\/x?|src$/g, "") ?? "",
  30. };
  31. });
  32.  
  33. $editor.on("change", updateLanguageSettings);
  34. $plainTextarea.on("input", updateLanguageSettings);
  35. document.addEventListener("paste", updateLanguageSettings);
  36. $("#input-open-file").on("change", () => { setTimeout(updateLanguageSettings, 0); });
  37.  
  38. function updateLanguageSettings() {
  39. const sourceCode = getSourceCode();
  40.  
  41. const languageInfomation = sourceCode.match(DETECTION_REG_EXP);
  42. if (!languageInfomation || !languageInfomation?.groups?.args) return;
  43.  
  44. let languageSelectors = languageInfomation.groups.args?.trim().replace(/\s+/g, " ").split(" ");
  45. languageSelectors = languageSelectors.map((selector) => selector.toLowerCase());
  46.  
  47. const selectedOption = languageOptions.find((option) => {
  48. return (
  49. languageSelectors.includes(option.id) ||
  50. languageSelectors.every((selector) => option.label.includes(selector)) ||
  51. languageSelectors.every((selector) => option.code.includes(selector))
  52. );
  53. });
  54.  
  55. if (!selectedOption) return;
  56.  
  57. $selectLanguage.val(selectedOption.id).trigger("change");
  58. }
  59.  
  60. async function rendered() {
  61. let timer;
  62. await new Promise((resolve) => {
  63. observer();
  64. function observer() {
  65. if (typeof CodeMirror == "function") {
  66. resolve();
  67. }
  68. timer = setTimeout(observer, 10);
  69. }
  70. });
  71. clearTimeout(timer);
  72. }
  73. })();