Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Confluence Auto Numbered Headings (Tampermonkey UserScript)

Description

This is a Tampermonkey userscript that adds a heading numbering feature to the page editor in Atlassian Confluence. This will number headings as follows:

1. Header 1

1.2 Header 2

1.2.3 Header 3

2. Header 1

Based on work by Markus Jenu at https://community.atlassian.com/t5/Confluence-questions/Is-it-possible-to-add-numbering-to-headings-in-Confluence/qaq-p/315517#M87046.

The original script was intended to be installed as a Confluence user macro. Adding macros requires admin rights to your Confluence instance. This script allows non-admin users to run this script locally.

Install

  1. Install the Tampermonkey extension for your web browser.
  2. Add Confluence Auto Numbered Headings to Tampermonkey from its home on Greasy Fork using the "Install this script" button. (The script you see here on GitHub auto-syncs to Greasy Fork.)
  3. Configure this script in Tampermonkey, if needed (see below).
  4. Edit any page in confluence. Add heading numbers using the new button shown in the screenshot:

screenshot

Configure

This script is pre-configured to work with Confluence instances hosted by Atlassian. If you run an internal / on-premises instance of Confluence, you'll need to change the script's settings in Tampermonkey as follows:

  1. Go to Tampermonkey > Dashboard.
  2. Under the "Installed userscripts" tab, click on the edit icon for Confluence Auto Numbered Headings.
  3. Click on the "Settings" tab.
  4. Under "Includes/Excludes" > "User matches", add the URL for your internal Confluence instance. The format should be something like https://confluence.companyintranet.com/*

Change Log

  • 2020-03-18 v0.4: Fixed a bug in which extra text was added to the end of headings that contained HTML. For example, <h3>Example <strong>Heading</strong></h3> would be changed to <h3>1.3 Example Heading <strong>Heading</strong></h3>.
  • 2020-03-20 v0.5: Fixed a bug in which the button failed to appear when creating a new page.
  • 2021-03-29 v0.6: Made compatible with Atlassian's new ProseMirror-based editor.
// ==UserScript==
// @name Confluence Auto Numbered Headings
// @namespace https://gist.github.com/elahd/28f64feddd9ece56f4f0566d195d0cbd
// @version 0.6
// @description Adds numbered headings button to the page editor in Atlassian Confluence. Based on work by Markus Jenu at https://community.atlassian.com/t5/Confluence-questions/Is-it-possible-to-add-numbering-to-headings-in-Confluence/qaq-p/315517#M87046.
// @author Elahd Bar-Shai
// @match https://*.atlassian.net/wiki/spaces/*
// @match https://*.atlassian.net/wiki/spaces/*
// @require https://greasyfork.org/scripts/5392-waitforkeyelements/code/WaitForKeyElements.js?version=115012
// @grant none
// ==/UserScript==
(function() {
'use strict';
var jQuery = window.jQuery;
var old_conf;
function addIndex() {
var indices = [];
if (old_conf) {
jQuery("#wysiwygTextarea_ifr").contents().find("h1,h2,h3,h4,h5,h6").each(function(i,e) {
var hIndex = parseInt(this.nodeName.substring(1)) - 1;
if (indices.length - 1 > hIndex) {
indices= indices.slice(0, hIndex + 1 );
}
if (indices[hIndex] == undefined) {
indices[hIndex] = 0;
}
indices[hIndex]++;
jQuery(this).html(indices.join(".")+". " + removeNo(jQuery(this).html()));
});
} else {
jQuery(".ak-editor-content-area .ProseMirror").find("h1,h2,h3,h4,h5,h6").each(function(i,e) {
var hIndex = parseInt(this.nodeName.substring(1)) - 1;
if (indices.length - 1 > hIndex) {
indices= indices.slice(0, hIndex + 1 );
}
if (indices[hIndex] == undefined) {
indices[hIndex] = 0;
}
indices[hIndex]++;
jQuery(this).html(indices.join(".")+". " + removeNo(jQuery(this).html()));
});
}
}
function removeNo(str) {
let newstr = str.trim();
newstr = newstr.replace(/[\u00A0\u1680​\u180e\u2000-\u2009\u200a​\u200b​\u202f\u205f​\u3000]/g,' ');
if(IsNumeric(newstr.substring(0,newstr.indexOf(' ')))){
return newstr.substring(newstr.indexOf(' ')+1).trim();
}
return newstr;
}
function IsNumeric(num) {
num = num.split('.').join("");
return (num >=0 || num < 0);
}
function createButton () {
old_conf = jQuery('.ProseMirror').length == 0 ? true : false;
if (old_conf) {
window.AJS.toInit(() => {
jQuery('#rte-toolbar > div.aui-toolbar2-primary.toolbar-primary').append('<ul class="aui-buttons rte-toolbar-group-link"><li class="toolbar-item" data-tooltip="Auto-Number Headings" id="addIndex"><a class="toolbar-trigger aui-button aui-button-subtle" href="#" ><span class="aui-icon aui-icon-small aui-iconfont-table-of-contents">Auto-Number Headings</span></a></li></ul>')
jQuery("#addIndex").click(function(e) {
e.preventDefault();
addIndex();
});
});
} else {
jQuery('.sc-kafWEX.eAQEwn > span').last().after('<span class="sc-jTzLTM jzOOfP"><div><div class="sc-cIShpX hVLmrw"><button aria-haspopup="false" class="css-1k4akzn" type="button" tabindex="0" id="addIndex" style="align-items:center"><span class="css-1ujqpe8"><span role="img" aria-label="Action item" class="css-1e9p0wv"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-list-stars" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M5 11.5a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5zm0-4a.5.5 0 0 1 .5-.5h9a.5.5 0 0 1 0 1h-9a.5.5 0 0 1-.5-.5z"/><path d="M2.242 2.194a.27.27 0 0 1 .516 0l.162.53c.035.115.14.194.258.194h.551c.259 0 .37.333.164.493l-.468.363a.277.277 0 0 0-.094.3l.173.569c.078.256-.213.462-.423.3l-.417-.324a.267.267 0 0 0-.328 0l-.417.323c-.21.163-.5-.043-.423-.299l.173-.57a.277.277 0 0 0-.094-.299l-.468-.363c-.206-.16-.095-.493.164-.493h.55a.271.271 0 0 0 .259-.194l.162-.53zm0 4a.27.27 0 0 1 .516 0l.162.53c.035.115.14.194.258.194h.551c.259 0 .37.333.164.493l-.468.363a.277.277 0 0 0-.094.3l.173.569c.078.255-.213.462-.423.3l-.417-.324a.267.267 0 0 0-.328 0l-.417.323c-.21.163-.5-.043-.423-.299l.173-.57a.277.277 0 0 0-.094-.299l-.468-.363c-.206-.16-.095-.493.164-.493h.55a.271.271 0 0 0 .259-.194l.162-.53zm0 4a.27.27 0 0 1 .516 0l.162.53c.035.115.14.194.258.194h.551c.259 0 .37.333.164.493l-.468.363a.277.277 0 0 0-.094.3l.173.569c.078.255-.213.462-.423.3l-.417-.324a.267.267 0 0 0-.328 0l-.417.323c-.21.163-.5-.043-.423-.299l.173-.57a.277.277 0 0 0-.094-.299l-.468-.363c-.206-.16-.095-.493.164-.493h.55a.271.271 0 0 0 .259-.194l.162-.53z"/></svg></span></span></button></div></div></span>');
jQuery("#addIndex").click(function(e) {
e.preventDefault();
addIndex();
});
}
}
// Wait for editor to load before creating button.
//LEGACY EDITOR
waitForKeyElements ("form#editpageform.editor.aui", createButton); //For editing existing pages.
waitForKeyElements ("form#createpageform.editor.aui", createButton); //For creating new pages.
//NEW EDITOR
waitForKeyElements (".sc-kafWEX.eAQEwn", createButton);
})();
@csuka

This comment has been minimized.

Copy link

@csuka csuka commented Mar 11, 2020

How can we enable this when our instance is hosted by Atlassian? What do you mean by it works out-of-the-box?
We currently don't see an option to install Macro's.

@elahd

This comment has been minimized.

Copy link
Owner Author

@elahd elahd commented Mar 18, 2020

Hey @csuka: This is intended to be used with the Tampermonkey browser plugin, which must be installed locally for every user. Tampermonkey is available for all major browsers. Once that's installed, you can install this script from its home on the Greasy Fork userscript repository.

@alpapanik

This comment has been minimized.

Copy link

@alpapanik alpapanik commented Sep 24, 2020

Hi,

After following the installation instructions, the script worked fine on Confluence 7.5.2 (with the old editor), but it doesn't seem to work with the new editor in Confluence cloud (current version 1000.0.0-a38692d0e846). Will there be an update anytime soon to work with the new editor?

@frankprill

This comment has been minimized.

Copy link

@frankprill frankprill commented Mar 19, 2021

Is there any update concerning this what alpapanik asked?

@elahd

This comment has been minimized.

Copy link
Owner Author

@elahd elahd commented Mar 30, 2021

@alpapanik @frankprill

Atlassian totally revamped Confluence's interface. I think I have this script working now in both the legacy and new editors, but my ability to test is limited. Try now w/ version 0.6.

@StaniAlex

This comment has been minimized.

Copy link

@StaniAlex StaniAlex commented Nov 10, 2021

Hello,
it seems the script does not work with Confluence 7.13.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment