AO3: Add Paragraph Breaks

Convert line breaks to paragraphs on Archive of our Own fics

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name AO3: Add Paragraph Breaks
// @description Convert line breaks to paragraphs on Archive of our Own fics
// @author the_wanlorn
// @version 1.0
// @license MIT
// @grant GM_getValue
// @grant GM_setValue
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js
// @require https://openuserjs.org/src/libs/sizzle/GM_config.js
// @include https://archiveofourown.org/works/*
// @include https://archiveofourown.org/*/works/*
// @include http://archiveofourown.org/works/*
// @include http://archiveofourown.org/*/works/*
// @namespace https://greasyfork.org/users/844343
// ==/UserScript==

(function ($) {
  var frame = document.createElement('div');
  document.body.appendChild(frame);

  var gmc = new GM_configStruct({
    'id': 'ao3_add_paragraphs',
    'title': 'AO3: Add Paragraphs Settings',
    'fields': {
      'autoFormat': {
        'label': 'Auto-Format Fics',
        'type': 'checkbox',
        'default': false
      },
      'doubleBreaks': {
        'label': 'Convert single paragraph breaks to double paragraph breaks',
        'type': 'checkbox',
        'default': false
      }
    },
    'frame': frame,
    'events': {
      'open': addStyling,
      'save': function () { gmc.close(); },
      'close': initFormat,
      'reset': function () { gmc.save(); }
    }
  });

  initFormat();

  /**
   * Add UI elements and potentially format the page, if autoformatting is
   * turned on.
   */
  function initFormat() {
    var auto_format = gmc.get('autoFormat'),
      double_breaks = gmc.get('doubleBreaks');

    if (auto_format) {
      formatPage(double_breaks);
    }

    addLinks(auto_format);
  }

  /**
   * Add UI elements
   *
   * @param {bool} auto_format Whether the page is to be formatted automatically.
   */
  function addLinks(auto_format) {
    var $header_menu = $('ul.primary.navigation.actions'),
      $menu_link = $('.ao3_add_pars_settings'),
      $format_button = $('.ao3_add_pars');

    // If we don't already have a menu link there, add it.
    if ($menu_link.length === 0) {
      $menu_link = $('<li class="ao3_add_pars_settings dropdown"></li>').html('<a>Format Settings</a>');
      $header_menu.find('li.search').before($menu_link);
      $menu_link.on('click', function () {
        // Remove the open class since it's not actually a dropdown, we're just
        // cribbing the styling.
        $(this).toggleClass('open');
        // Open the settings dialogue
        gmc.open();
      });
    }

    // If we're not autoformatting the page, add a button to trigger it.
    if (!auto_format && $format_button.length === 0) {
      $format_button = $('<input class="button ao3_add_pars" type="button" value="Format Page"></input>');
      $format_button.css('marginLeft', '1em').css('marginRight', '1em');
      $header_menu.find('#search').prepend($format_button);
      $format_button.on('click', function() {
        var double_breaks = gmc.get('doubleBreaks');
        formatPage(double_breaks);
      });
    }
    // Otherwise, if we are autoformatting, get rid of the button.
    else if (auto_format && $format_button) {
      $format_button.remove();
    }
  }

  /**
   * Replace the current tags with the new tags.
   *
   * @param {bool} double Whether to add a double <br> tag to already-existing <p> tags.
   */
  function formatPage(double) {
    var $chapters = $('#chapters'),
      html_string = $chapters.html();

    if (double) {
      html_string = html_string.replaceAll('</p>', '<dblbrkspc></p>');
    }

    html_string = html_string.replaceAll('<br>', '</p><p>');

    if (double) {
      html_string = html_string.replaceAll('<dblbrkspc>', '<br /><br />');
    }

    $chapters.html(html_string);
  }

  /**
   * Add the required styling to the settings dialogue.
   *
   * @param {Object} document The document the given frame is in.
   * @param {Object} window   The window of the given frame.
   * @param {Object} frame    The frame to add styling to.
   */
  function addStyling(document, window, frame) {
    var frame_style = 'border: 1px solid #000; left: 50%; position: fixed; '
      + 'top: 50%; width: 310px; z-index: 9999; transform: translate(-50%, -50%);',
      $frame_obj = $(frame);

    $frame_obj.attr('style', frame_style);
    $frame_obj.find('#ao3_add_paragraphs_closeBtn').hide();
    $frame_obj.find('.field_label').css({"font-size": "1em", "font-weight": "400"});
    $frame_obj.find('.config_header').css({"font-size": "2em", "paddingBottom": "1em"});
    $frame_obj.find('.config_var').css({"margin": "0 0 10px 40px", "position": "relative"});
    $frame_obj.find('input[type="checkbox"]').css({"position": "absolute", "left": "-25px", "top": "0"});
  }
})(jQuery);