AtCoder Beautiful Code View

AtCoderの提出コードをMonaco Editorを使用した表示にします

  1. // ==UserScript==
  2. // @name AtCoder Beautiful Code View
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.3
  5. // @description AtCoderの提出コードをMonaco Editorを使用した表示にします
  6. // @author Chippppp
  7. // @license MIT
  8. // @match https://atcoder.jp/contests/*/submissions/*
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12. "use strict";
  13.  
  14. (function() {
  15. // 対応言語
  16. const languages = new Set(["plaintext", "abap", "apex", "azcli", "bat", "bicep", "cameligo", "clojure", "coffeescript", "c", "cpp", "csharp", "csp", "css", "dart", "dockerfile", "ecl", "elixir", "flow9", "fsharp", "freemarker2", "freemarker2.tag-angle.interpolation-dollar", "freemarker2.tag-bracket.interpolation-dollar", "freemarker2.tag-angle.interpolation-bracket", "freemarker2.tag-bracket.interpolation-bracket", "freemarker2.tag-auto.interpolation-dollar", "freemarker2.tag-auto.interpolation-bracket", "go", "graphql", "handlebars", "hcl", "html", "ini", "java", "javascript", "julia", "kotlin", "less", "lexon", "lua", "liquid", "m3", "markdown", "mips", "msdax", "mysql", "objective-c", "pascal", "pascaligo", "perl", "pgsql", "php", "pla", "postiats", "powerquery", "powershell", "proto", "pug", "python", "qsharp", "r", "razor", "redis", "redshift", "restructuredtext", "ruby", "rust", "sb", "scala", "scheme", "scss", "shell", "sol", "aes", "sparql", "sql", "st", "swift", "systemverilog", "verilog", "tcl", "twig", "typescript", "vb", "xml", "yaml", "json"]);
  17.  
  18. // 言語名を取得
  19. let lang = document.getElementsByClassName("text-center")[3].innerText;
  20. lang = lang.slice(0, lang.indexOf(" ")).toLocaleLowerCase().replace("#", "sharp");
  21. if (lang.startsWith("pypy")) lang = "python";
  22. else if (lang == "c++") lang = "cpp";
  23.  
  24. // 非対応言語の場合終了
  25. if (!languages.has(lang)) return;
  26.  
  27. // Monaco Editor in cdnjs
  28. // Copyright (c) 2016 - present Microsoft Corporation
  29. let script = document.createElement("script");
  30. script.src = "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.33.0/min/vs/loader.min.js";
  31. document.head.prepend(script);
  32.  
  33. // 元のエディターを非表示
  34. let header = document.createElement("script");
  35. header.innerHTML = `
  36. document.getElementsByClassName("linenums")[0].style.display = "none";
  37. document.getElementsByClassName("btn-text toggle-btn-text source-code-expand-btn")[0].style.display = "none";
  38. document.getElementsByClassName("btn-copy btn-pre")[0].style.zIndex = "1";
  39. document.getElementsByClassName("btn-copy btn-pre")[0].style.borderRadius = "0";
  40. document.getElementsByClassName("btn-copy btn-pre")[1].style.zIndex = "1";
  41. document.getElementsByClassName("btn-copy btn-pre")[1].style.borderRadius = "0";
  42. `
  43. document.head.prepend(header);
  44.  
  45. // 新しいエディターの作成
  46. let div = document.createElement("div");
  47. div.style.marginTop = "10px";
  48. div.style.marginBottom = "30px";
  49. document.getElementById("submission-code").after(div);
  50.  
  51. // コードを取得
  52. let str = document.getElementById("for_copy0").innerText;
  53.  
  54. // 行数を取得
  55. let cnt;
  56. let arr = str.match(/\n/g);
  57. if (arr == null) cnt = 0;
  58. else cnt = arr.length;
  59. console.log(cnt);
  60. div.style.height = Math.min(510, (cnt + 1) * 21 + 6).toString() + "px";
  61.  
  62. // Monaco Editorがロードされたらエディターを色付けする
  63. script.onload = function() {
  64. require.config({ paths: { "vs": "https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.33.0/min/vs" } });
  65.  
  66. require(["vs/editor/editor.main"], function() {
  67. monaco.editor.create(div, {
  68. value: str,
  69. language: lang,
  70. theme: "vs-dark",
  71. readOnly: true,
  72. lineHeight: 21,
  73. });
  74. document.getElementsByClassName("monaco-editor")[0].style.paddingTop = "20px";
  75. });
  76. };
  77. })();