Comparing version 0.0.1 to 0.1.0
interface Options { | ||
locale?: string; | ||
backlinkPos?: "start" | "end"; | ||
numberFormat?: string | ((n: number) => string); | ||
dataAttributePostfix?: string; | ||
enableBacklinks?: boolean; | ||
backlinkPos?: 'start' | 'end'; | ||
backlinkSymbol?: string; | ||
jumpTexts?: { | ||
jumpUp?: string; | ||
jumpBackUp?: string; | ||
jumpUpTo?: string; | ||
}; | ||
getBacklinkIdentifier?: (n: number) => string; | ||
getListStyleTypeStr?: (formattedNum: string) => string; | ||
ignoreIndicatorOfFirstCategory?: boolean; | ||
ignoreIndicatorOfCategory?: string; | ||
enableBrackets?: boolean; | ||
sep?: string; | ||
targetedBacklinkClassName?: string; | ||
backlinksWrapperClassName?: string; | ||
} | ||
declare function initPadatika(idToInitialMap: { | ||
declare function padatika(categoryIdToCategoryIndicatorMap: { | ||
[x: string]: string; | ||
}, { locale, backlinkPos, backlinkSymbol, getBacklinkIdentifier, }?: Options): void; | ||
}, { numberFormat, dataAttributePostfix, enableBacklinks, backlinkPos, backlinkSymbol, jumpTexts, getBacklinkIdentifier, getListStyleTypeStr, ignoreIndicatorOfFirstCategory, ignoreIndicatorOfCategory, enableBrackets, sep, targetedBacklinkClassName, backlinksWrapperClassName, }?: Options): void; | ||
export { initPadatika as default }; | ||
export { padatika as default }; |
@@ -1,2 +0,2 @@ | ||
function k(f,l){let p=document.createElement(f);return l&&(p.className=l),p}function y(f){let l=f,p=0;for(;document.getElementById(l);)l=`${f}-${p++}`;return l}function q(f){let l=!1,p="";function T(N){if(l)return;let u=N.childNodes;for(let L=0;L<u.length;L++){if(l)return;let m=u[L];if(m.nodeType===Node.TEXT_NODE){let g=m.data.trim();if(g.length!=0){l=!0;let $=/^\[([\w-]+)\]\s*?/,H=g.match($);H&&(p=H[1],m.data=m.data.replace($,""));return}else continue}else if(m.nodeType===Node.ELEMENT_NODE)T(m);else continue}}return T(f),p}var W={locale:"en-US",backlinkPos:"start",backlinkSymbol:"\u2191"};function I(f,{locale:l="en-US",backlinkPos:p="start",backlinkSymbol:T="\u2191",getBacklinkIdentifier:N}=W){var O,S,A,w;N==null&&(N=s=>(s+1).toLocaleString(l,{useGrouping:!1}));let u={},L={},m={},g=()=>{},$=!1;for(let[s,x]of Object.entries(f)){let r=document.querySelector(`#${s}`);if(!r){console.error(`Padatika error: Heading with id ${s} doesn't exist`);continue}L[s]=r;let t=((O=r==null?void 0:r.nextElementSibling)==null?void 0:O.tagName)=="UL"&&r.nextElementSibling;if(t){t.remove();for(let n=0;n<t.children.length;n++){let e=t.children[n],i=q(e);if(i!=""){let a=`${s}:${i}`;if(u[a])console.warn(`Footnote ignored for duplicate name(${i}) in same category(${s}): ${e.textContent}`);else{let o=k("span","backlink-wrapper");if(e.id=y(`padatika-${a}`),u[a]={li:e,backlinksWrapper:o,refs:[],refsNum:0},p=="end")if(((S=e.lastElementChild)==null?void 0:S.tagName)=="P"){let h=e.lastElementChild,c=h.nextSibling;(c==null?void 0:c.nodeType)===Node.TEXT_NODE&&c.wholeText.trim()!=""?e.append(o):h.append(o)}else e.append(o);else if(p=="start")if(((A=e.firstElementChild)==null?void 0:A.tagName)=="P"){let h=e.firstElementChild,c=h.previousSibling;(c==null?void 0:c.nodeType)===Node.TEXT_NODE&&c.wholeText.trim()!=""?e.prepend(o):h.prepend(o)}else e.prepend(o)}}else console.warn(`Footnote lacks a name: ${e.textContent}`)}}}let H=[...document.querySelectorAll("[data-padatika]")];if(H.length==0)return;let P=(w=Object.entries(f).find(s=>s[1]===""))==null?void 0:w[0];H.forEach(s=>{var e;let x=/^(([\w-]+):)?([\w-]+)?$/,r=s.textContent.trim().match(x),t=k("a"),n=(i,a,o)=>{s.replaceChildren(t),t.textContent=`[${a}]`,o&&(t.href=o),i&&(t.style.color="red"),s.removeAttribute("data-padatika")};if(r){let i=r[3],a=r[2]||P;if(a===void 0)n(!0,"No default Category exists");else{let o=L[a],h=f[a],c=h?h+" ":"";if(o){let b=(e=u[`${a}:${i}`])==null?void 0:e.li;if(b){let E=u[`${a}:${i}`];if(E.refs.push(t),t.id=y(`${b.id}-ref-${E.refs.length}`),t.addEventListener("click",()=>{if(g(),E.refs.length>1){let d=E.backlinksWrapper,M=d.querySelector(`[href="#${t.id}"]`),v="padatika-targeted-backlink";g=()=>{$&&(M.classList.remove(v),d.firstChild.replaceWith(T),$=!1)},M.classList.add(v);let C=k("a");C.textContent=T,C.href=M.href,C.addEventListener("click",g),d.firstChild.replaceWith(C),$=!0}}),m[a]){if(E.refs.length===1){let d=m[a];d.parentOL.append(b),d.uniqueRefCount++,E.refsNum=d.uniqueRefCount}n(!1,`${c}${E.refsNum}`,`#${b.id}`)}else{let d=k("ol");d.append(b),m[a]={uniqueRefCount:1,parentOL:d},E.refsNum=1,n(!1,`${c}1`,`#${b.id}`),o.insertAdjacentElement("afterend",d)}}else n(!0,"Target not found")}else n(!0,"Category not matched")}}else n(!0,"Invalid ref syntax")}),Object.entries(u).forEach(([s,x])=>{let r=x.refs.length,t=x.backlinksWrapper;if(r==0)console.warn(`Footnote of identifier "${s}" have no references.`);else if(r==1){let n=k("a");n.textContent=T,n.href=`#${x.refs[0].id}`,t.append(n),n.addEventListener("click",()=>g())}else t.append(T),x.refs.forEach((n,e)=>{let i=k("a"),a=k("sup");a.append(i),t.append(a),i.href=`#${n.id}`,i.textContent=N(e),i.addEventListener("click",()=>g())})})}export{I as default}; | ||
var Y=Object.defineProperty;var _=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var X=(a,t,n)=>t in a?Y(a,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[t]=n,A=(a,t)=>{for(var n in t||(t={}))Z.call(t,n)&&X(a,n,t[n]);if(_)for(var n of _(t))ee.call(t,n)&&X(a,n,t[n]);return a};function h(a,t){let n=document.createElement(a);return t&&(n.className=t),n}function j(a){let t=a,n=0;for(;document.getElementById(t);)t=`${a}-${n++}`;return t}function O(a,t){return typeof t=="string"?a.toLocaleString(`en-u-nu-${t}`,{useGrouping:!1}):t(a)}function G(a){let t=!1,n="";function N(M){if(t)return;let E=M.childNodes;for(let l=0;l<E.length;l++){if(t)return;let m=E[l];if(m.nodeType===Node.TEXT_NODE){let L=m.data.trim();if(L.length!=0){t=!0;let C=/^\[([\w-]+)\]\s*/,T=L.match(C);T&&(n=T[1],m.data=m.data.replace(C,""));return}else continue}else if(m.nodeType===Node.ELEMENT_NODE)N(m);else continue}}return N(a),n}var I="Padatika",B={jumpUp:"Jump up",jumpBackUp:"Jump back up",jumpUpTo:"Jump up to: "},te={numberFormat:"latn",dataAttributePostfix:"fnref",enableBacklinks:!0,backlinkPos:"start",backlinkSymbol:"\u2191",jumpTexts:B,ignoreIndicatorOfFirstCategory:!0,enableBrackets:!0,sep:" ",targetedBacklinkClassName:"targeted-backlink",backlinksWrapperClassName:"backlinks-wrapper"};function ne(a,{numberFormat:t="latn",dataAttributePostfix:n="fnref",enableBacklinks:N=!0,backlinkPos:M="start",backlinkSymbol:E="\u2191",jumpTexts:l=B,getBacklinkIdentifier:m,getListStyleTypeStr:L,ignoreIndicatorOfFirstCategory:C=!0,ignoreIndicatorOfCategory:T,enableBrackets:Q=!0,sep:z=" ",targetedBacklinkClassName:q="targeted-backlink",backlinksWrapperClassName:K="backlinks-wrapper"}=te){var P,D,J;m===void 0&&(m=i=>O(i,t)),L===void 0&&(L=i=>`${i}. `),l=A(A({},B),l);let S={},W={},v={},$=()=>{},H=!1,U="",F=[],w=[];for(let i of Object.keys(a)){let c=document.querySelector(`#${i}`);if(!c)continue;U+=`${U==""?"":" ,"}#${i}`,W[i]=c;let f=((P=c==null?void 0:c.nextElementSibling)==null?void 0:P.tagName)=="UL"&&c.nextElementSibling;if(f){F.push(f);for(let s=0;s<f.children.length;s++){let e=f.children[s],g=G(e);if(g!=""){let r=`${i}:${g}`;if(S[r])console.warn(`${I}: Footnote ignored for duplicate name(${g}) in category(${i}).`),w.push(e);else{let o=h("span",K);if(e.id=j(`fn-${r}`),S[r]={li:e,backlinksWrapper:o,refs:[],indexLocaleStr:""},N){if(M=="end")if(((D=e.lastElementChild)==null?void 0:D.tagName)=="P"){let k=e.lastElementChild,p=k.nextSibling;(p==null?void 0:p.nodeType)===Node.TEXT_NODE&&p.wholeText.trim()!=""?e.append(o):k.append(o)}else e.append(o);else if(M=="start"){if(((J=e.firstElementChild)==null?void 0:J.tagName)=="P"){let k=e.firstElementChild,p=k.previousSibling;(p==null?void 0:p.nodeType)===Node.TEXT_NODE&&p.wholeText.trim()!=""?e.prepend(o):k.prepend(o)}else e.prepend(o);o.insertAdjacentText("afterend"," ")}}}}else console.warn(`${I}: Footnote lacks a name or has invalid one: ${e.textContent}`),w.push(e)}}}let V=U!=""?document.querySelector(U).id:null;w.forEach(i=>i.remove());let R=[...document.querySelectorAll(`[data-${n}]`)];R.length!=0&&(F.forEach(i=>i.remove()),R.forEach(i=>{let c=/^([\w-]+):([\w-]+)$/,f=i.textContent.trim().match(c),s=h("a"),e=(g,r,o)=>{i.replaceChildren(s),s.innerHTML=Q?`[${r}]`:r,o&&(s.href=o),g&&(s.style.color="red")};if(f){let g=f[2],r=f[1],o=W[r],p=a[r]+z;if(C&&!T?r===V&&(p=""):T&&r===T&&(p=""),o){let d=S[`${r}:${g}`],b=d==null?void 0:d.li;if(b)if(d.refs.push(s),s.id=j(`${b.id}-ref-${d.refs.length}`),s.addEventListener("click",()=>{$();let u=d.backlinksWrapper,x=u.querySelector(`[href="#${s.id}"]`);if(d.refs.length>1){$=()=>{H&&(x.classList.remove(q),u.firstChild.replaceWith(E),H=!1)},x.classList.add(q);let y=h("a");y.textContent=E,y.href=x.href,y.title=l.jumpBackUp,y.ariaLabel=l.jumpBackUp,y.addEventListener("click",$),u.firstChild.replaceWith(y)}else x.title=l.jumpBackUp,x.ariaLabel=l.jumpBackUp,$=()=>{H&&(x.title=l.jumpUp,x.ariaLabel=l.jumpUp,H=!1)};H=!0}),i.insertAdjacentHTML("beforebegin","⁠"),v[r]){if(d.refs.length===1){let u=v[r];u.uniqueRefCount++,d.indexLocaleStr=O(u.uniqueRefCount,t),b.style.listStyleType=`"${L(d.indexLocaleStr)}"`,u.parentOL.append(b)}e(!1,`${p}${d.indexLocaleStr}`,`#${b.id}`)}else{d.indexLocaleStr=O(1,t);let u=h("ol");b.style.listStyleType=`"${L(d.indexLocaleStr)}"`,u.append(b),v[r]={uniqueRefCount:1,parentOL:u},e(!1,`${p}${d.indexLocaleStr}`,`#${b.id}`),o.insertAdjacentElement("afterend",u)}else e(!0,"Target not found")}else e(!0,f.input)}else e(!0,"Invalid ref syntax")}),Object.entries(S).forEach(([i,c])=>{let f=c.refs.length,s=c.backlinksWrapper;if(f==0)console.warn(`${I}: Footnote("${i}") lacks references.`),c.li.querySelector(`[data-${n}]`)&&console.error(`${I}: Reference from orphan footnote(${i}) exists!`);else if(N)if(f==1){let e=h("a");e.textContent=E,e.href=`#${c.refs[0].id}`,e.title=l.jumpUp,e.ariaLabel=l.jumpUp,s.append(e),e.addEventListener("click",()=>$())}else s.append(E),c.refs.forEach((e,g)=>{let r=h("a"),o=h("sup");if(o.append(r),s.append(o),r.href=`#${e.id}`,r.textContent=m(g+1),r.addEventListener("click",()=>$()),g==0){let k=h("span");k.textContent=l.jumpUpTo,k.setAttribute("style","top: -99999px; clip: rect(1px,1px,1px,1px); position: absolute !important; padding: 0 !important; border: 0 !important; height: 1px !important; width: 1px !important; overflow: hidden;"),r.prepend(k)}})}))}export{ne as default}; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "padatika", | ||
"version": "0.0.1", | ||
"description": "A customizable footnote system inspired by wikipedia.", | ||
"version": "0.1.0", | ||
"description": "A modern footnote system for the web.", | ||
"type": "module", | ||
"types": "./dist/index.d.ts", | ||
"browser": "./dist/index.js", | ||
"exports": { | ||
@@ -25,8 +26,16 @@ ".": { | ||
"devDependencies": { | ||
"@eslint/js": "^8.57.0", | ||
"eslint": "^8.57.0", | ||
"prettier": "3.2.5", | ||
"tsup": "^8.0.2", | ||
"typescript": "^5.4.2" | ||
"typescript": "^5.4.3", | ||
"typescript-eslint": "^7.6.0" | ||
}, | ||
"scripts": { | ||
"build": "tsup src/index.ts --format esm --minify --sourcemap --dts" | ||
"build": "tsup src/index.ts --clean --format esm --minify --sourcemap --dts", | ||
"lint": "eslint .", | ||
"lint-fix": "eslint . --fix", | ||
"check-format": "prettier . --check", | ||
"format": "prettier . --write" | ||
} | ||
} |
538
README.md
@@ -1,112 +0,530 @@ | ||
# Padatika | ||
[](https://www.jsdelivr.com/package/npm/padatika) | ||
Padatika helps you to have wikipedia like footnote system in your own website easily. | ||
# ð Padatika | ||
Caution: This tool is not yet stable, so DO NOT use it in production. | ||
Got frustrated with managing footnotes manually? Padatika can help. | ||
## Installation | ||
For better viewing, [read this doc from Github](https://github.com/ashutoshbw/padatika/blob/v0.1.0/README.md). | ||
Add the following script element in the `<head>` of your HTML: | ||
## ðĶ Features | ||
- âĻ Sorts footnotes automatically. | ||
- ðĒ No need to manually number your references. | ||
- ð You can easily organize your footnotes into different categories. | ||
- âĪīïļ Wikipedia-like backlinks. | ||
- ð Localization. | ||
- âŋ Accessibility. | ||
- ð ïļ Super customizable with over a dozen options. | ||
## ð Getting started | ||
> [!CAUTION] | ||
> Examples with cats, dogs and ðĐ ahead. | ||
Let's see an example to get familier with Padatika quickly. | ||
First, load Padatika and initialize it like below: | ||
```html | ||
<script type="importmap"> | ||
{ | ||
"imports": { | ||
"padatika": "https://esm.sh/padatika" | ||
} | ||
} | ||
<script type="module"> | ||
import padatika from 'https://cdn.jsdelivr.net/npm/padatika@0.1.0/dist/index.js'; | ||
padatika({ notes: 'N' }); | ||
</script> | ||
``` | ||
Now you can use it your script in the ESM way: | ||
> [!TIP] | ||
> Above `padatika` is a default export. So you can name it anything else if you wish. But here, I will stick to this name. | ||
Now in the `<body>` of your HTML, paste the following: | ||
```html | ||
<script type="module"> | ||
import initPadatika from "padatika"; | ||
</script> | ||
I like cats.<sup data-fnref>notes:cats</sup> | ||
I like dogs.<sup data-fnref>notes:dogs</sup> | ||
<h2 id="notes">Notes</h2> | ||
<ul> | ||
<li>[cats] meow meow</li> | ||
<li>[dogs] woof woof</li> | ||
</ul> | ||
``` | ||
## Concepts | ||
Now load the page in your browser with a local web server. You should see something like this: | ||
In different contexts footnotes might have different meanings. Let's first clear it out what I mean by footnote here. | ||
 | ||
> Footnote is a text at the bottom part of the main content of a webpage that is linked to somewhere else in that page to give some more information. | ||
Here, as you can see padatika automatically numbers for your footnotes. and add backlinks at the start of footnotes. | ||
So a footnote can is not limited to just your personal note on something, it can be a reference of a book, a glossary item etc. | ||
You've probably guessed how the linking is happening between footnotes and its references. Let's be clear about it and a few other things now so you can understand the rest of the doc easily: | ||
You can mix all kinds of footnotes in a single section possibly with a heading named "Footnotes". You can also categorize them into multiple sections with headings possibly like "Notes", "References", "Glossary" etc. | ||
- First, footnotes in padatika are organized by categories. A category is just a part of document starting with a heading element with an id containing the category name. In most case you will need just one or two categories, but you can have as many categories as you like in a similar fashion. You tell padatika to look for a category by passing its name as a key of a property of the object that you pass to `padatika`. We will see the role of the value of this property in a minute. First let's cover few other things. | ||
- Below the category heading, you have to write your footnotes in `<li>` elements wrapped in an unordered list(`<ul>`). Padatika will convert it to an ordered list and sort your footnotes to match references order. | ||
- Each footnote must start with a **name** wrapped with square brackets(`[]`) that is unique within the corresponding category. A name can be composed of a combination lowercase or uppercase English alphabets, numbers, dash(`-`) and underscore(`_`). | ||
- To create a reference you have to use the following template: `<sup data-fnref>category_name:footnote_name</sup>`. For example, `<sup data-fnref>notes:cats</sup>` means, it links to a footnote of name `cats` under the `notes` category. Here `data-fnref` empty data attribute is used by padaika by default to collect the references for processing. | ||
- Now let's talk about the `'N'` value given to the `notes` key in the object passed to `padatika` call. It's a footnote category indicator that you may want to see in your rendered references. In the example above it has no effect because by default Padatika doesn't show the category indicator for the first category that appears in the document. However it will appear if there is another category that comes before the "notes" category. You can also set the option [`ignoreIndicatorOfFirstCategory`](#ignoreindicatoroffirstcategory) to `false` to make sure all category indicators appear. Options are set by passing another object to `padatika`. So the call to `padatika` in this case will look like below: | ||
## How to tell Padatika what you want to do | ||
```js | ||
padatika({ notes: 'N' }, { ignoreIndicatorOfFirstCategory: false }); | ||
``` | ||
It all starts with initialzing padatika by passing an object to it. Below is an example: | ||
Result: | ||
 | ||
## ð§Đ Syntax of `padatika` | ||
```js | ||
initPadatika({ notes: "" }); | ||
padatika(categoryIdToCategoryIndicatorMap); | ||
padatika(categoryIdToCategoryIndicatorMap, options); | ||
``` | ||
Here `notes` is your choosen id of the heading element of a category of footnotes you want to create. We will see very soon the role of the `""` that is passed to `notes`. Padatika will look for the heading element with id `notes`. The HTML for the heading would possibly will look like below: | ||
### `categoryIdToCategoryIndicatorMap`(required) | ||
We have already seen how this object looks like and an example with one category in the [Getting started](#-getting-started) section. If you haven't read that section, read it first. Assuming you have read it, here goes a little involved example: | ||
<img src="./example-with-two-categories.png"> | ||
<details> | ||
<summary>Can you guess the code? Click to reveal it.</summary> | ||
```html | ||
<script type="module"> | ||
import padatika from 'https://cdn.jsdelivr.net/npm/padatika@0.1.0/dist/index.js'; | ||
padatika({ notes: 'N', refs: 'R' }); | ||
</script> | ||
I like cats.<sup data-fnref>notes:cats</sup> | ||
I like dogs.<sup data-fnref>notes:dogs</sup> | ||
I smell something.<sup data-fnref>refs:something</sup> | ||
<h2 id="notes">Notes</h2> | ||
<ul> | ||
<li>[cats] meow meow</li> | ||
<li>[dogs] woof woof</li> | ||
</ul> | ||
<h2 id="refs">References</h2> | ||
<ul> | ||
<li>[something] dog ðĐ</li> | ||
</ul> | ||
``` | ||
Now let's create some footnotes. We have to create footnote in an unordered list. Padatika will make it ordered list and take care the hassle of ordering them in the right way. Each footnote must appear in `<li>` inside it and each should start with a unique name enclosed in square brackets like below: | ||
</details> | ||
### `options`(optional) | ||
Here you can pass a optional object specifying options to configure padatika. The available options are: | ||
- `numberFormat` | ||
- `dataAttributePostfix` | ||
- `enableBacklinks` | ||
- `backlinkPos` | ||
- `backlinkSymbol` | ||
- `jumpTexts` | ||
- `getBacklinkIdentifier` | ||
- `getListStyleTypeStr` | ||
- `ignoreIndicatorOfFirstCategory` | ||
- `ignoreIndicatorOfCategory` | ||
- `enableBrackets` | ||
- `sep` | ||
- `targetedBacklinkClassName` | ||
- `backlinksWrapperClassName` | ||
Head over to [All option](#%EF%B8%8F-all-options) section to read their purpose and possible values. | ||
## ð ïļ All options | ||
### `numberFormat` | ||
Type: `string | ((n: number) => string)` | ||
Default value: `latn`(i.e. [Latin digits](https://en.wikipedia.org/wiki/Arabic_numerals)) | ||
You can use this option to easily change the language/format of numbers in reference supscripts and footnotes. | ||
For your convenience the following table describes all formats: | ||
<details> | ||
<summary>Click to expand table</summary> | ||
| Format | Description | | ||
| -------- | -------------------------------------------------------------------------- | | ||
| adlm | Adlam digits | | ||
| ahom | Ahom digits | | ||
| arab | Arabic-Indic digits | | ||
| arabext | Extended Arabic-Indic digits | | ||
| armn | Armenian upper case numerals â algorithmic | | ||
| armnlow | Armenian lower case numerals â algorithmic | | ||
| bali | Balinese digits | | ||
| beng | Bengali digits | | ||
| bhks | Bhaiksuki digits | | ||
| brah | Brahmi digits | | ||
| cakm | Chakma digits | | ||
| cham | Cham digits | | ||
| cyrl | Cyrillic numerals â algorithmic | | ||
| deva | Devanagari digits | | ||
| diak | Dives Akuru digits | | ||
| ethi | Ethiopic numerals â algorithmic | | ||
| finance | Financial numerals â may be algorithmic | | ||
| fullwide | Full width digits | | ||
| geor | Georgian numerals â algorithmic | | ||
| gong | Gunjala Gondi digits | | ||
| gonm | Masaram Gondi digits | | ||
| grek | Greek upper case numerals â algorithmic | | ||
| greklow | Greek lower case numerals â algorithmic | | ||
| gujr | Gujarati digits | | ||
| guru | Gurmukhi digits | | ||
| hanidays | Han-character day-of-month numbering for lunar/other traditional calendars | | ||
| hanidec | Positional decimal system using Chinese number ideographs as digits | | ||
| hans | Simplified Chinese numerals â algorithmic | | ||
| hansfin | Simplified Chinese financial numerals â algorithmic | | ||
| hant | Traditional Chinese numerals â algorithmic | | ||
| hantfin | Traditional Chinese financial numerals â algorithmic | | ||
| hebr | Hebrew numerals â algorithmic | | ||
| hmng | Pahawh Hmong digits | | ||
| hmnp | Nyiakeng Puachue Hmong digits | | ||
| java | Javanese digits | | ||
| jpan | Japanese numerals â algorithmic | | ||
| jpanfin | Japanese financial numerals â algorithmic | | ||
| jpanyear | Japanese first-year Gannen numbering for Japanese calendar | | ||
| kali | Kayah Li digits | | ||
| kawi | Kawi digits | | ||
| khmr | Khmer digits | | ||
| knda | Kannada digits | | ||
| lana | Tai Tham Hora (secular) digits | | ||
| lanatham | Tai Tham Tham (ecclesiastical) digits | | ||
| laoo | Lao digits | | ||
| latn | Latin digits | | ||
| lepc | Lepcha digits | | ||
| limb | Limbu digits | | ||
| mathbold | Mathematical bold digits | | ||
| mathdbl | Mathematical double-struck digits | | ||
| mathmono | Mathematical monospace digits | | ||
| mathsanb | Mathematical sans-serif bold digits | | ||
| mathsans | Mathematical sans-serif digits | | ||
| mlym | Malayalam digits | | ||
| modi | Modi digits | | ||
| mong | Mongolian digits | | ||
| mroo | Mro digits | | ||
| mtei | Meetei Mayek digits | | ||
| mymr | Myanmar digits | | ||
| mymrshan | Myanmar Shan digits | | ||
| mymrtlng | Myanmar Tai Laing digits | | ||
| nagm | Nag Mundari digits | | ||
| native | Native digits | | ||
| newa | Newa digits | | ||
| nkoo | N'Ko digits | | ||
| olck | Ol Chiki digits | | ||
| orya | Oriya digits | | ||
| osma | Osmanya digits | | ||
| rohg | Hanifi Rohingya digits | | ||
| roman | Roman upper case numerals â algorithmic | | ||
| romanlow | Roman lowercase numerals â algorithmic | | ||
| saur | Saurashtra digits | | ||
| segment | Legacy computing segmented digits | | ||
| shrd | Sharada digits | | ||
| sind | Khudawadi digits | | ||
| sinh | Sinhala Lith digits | | ||
| sora | Sora_Sompeng digits | | ||
| sund | Sundanese digits | | ||
| takr | Takri digits | | ||
| talu | New Tai Lue digits | | ||
| taml | Tamil numerals â algorithmic | | ||
| tamldec | Modern Tamil decimal digits | | ||
| tnsa | Tangsa digits | | ||
| telu | Telugu digits | | ||
| thai | Thai digits | | ||
| tirh | Tirhuta digits | | ||
| tibt | Tibetan digits | | ||
| traditio | Traditional numerals â may be algorithmic | | ||
| vaii | Vai digits | | ||
| wara | Warang Citi digits | | ||
| wcho | Wancho digits | | ||
</details> | ||
See the [Unicode CLDR Project's `numbers.xml`](https://github.com/unicode-org/cldr/blob/main/common/bcp47/number.xml) file for up to date list of them. | ||
If some of the these format doesn't have implementation or you need to format/translate it in a different way, you can also pass a function to this option. This function takes in a javascript number and and should return a string of the formatted/translated number of your desired way. | ||
If you want to format the numbers in Bengali, here is an example: | ||
<details> | ||
<summary>Click to see the example</summary> | ||
 | ||
Code: | ||
```html | ||
<script type="module"> | ||
import padatika from 'https://cdn.jsdelivr.net/npm/padatika@0.1.0/dist/index.js'; | ||
padatika({ notes: 'N', refs: 'R' }, { numberFormat: 'beng' }); | ||
</script> | ||
I like cats.<sup data-fnref>notes:cats</sup> | ||
I like dogs.<sup data-fnref>notes:dogs</sup> | ||
I smell something.<sup data-fnref>refs:something</sup> | ||
<h2 id="notes">Notes</h2> | ||
<ul> | ||
<li>[example1] This is my first example footnote.</li> | ||
<li>[example2] This is my second example footnote.</li> | ||
<li>[example3] This is my third example footnote.</li> | ||
<li>[cats] meow meow</li> | ||
<li>[dogs] woof woof</li> | ||
</ul> | ||
<h2 id="refs">References</h2> | ||
<ul> | ||
<li>[something] dog ðĐ</li> | ||
</ul> | ||
``` | ||
Now let's see how to create references to them. To create a reference to a footnote you have to create a `<sup>` element with the `data-padatika` empty attribute containing the name of the category, a colon and then the name of the footnote: | ||
</details> | ||
### `dataAttributePostfix` | ||
Type: `string` | ||
Default value: `fnref` | ||
By default Padatika looks for elements having the `data-fnref` data attribute to detect them as references to footnotes. This options allow you to choose a different data attribute for this purpose. For example if want `data-ref` instead of `data-fnref`, you could pass just the postfix part, that is, `'ref'` to this option. | ||
> [!CAUTION] | ||
> Since you might have a lot of markdown/HTML files depended on this, changing this value would also require you to change the data attribute on each of these files. So it's better to stick with some specific value of this option from the start. | ||
### `enableBacklinks` | ||
Type: `boolean` | ||
Default value: `true` | ||
This option allows you to turn on/off backlinks in the footnotes. | ||
### `backlinkPos` | ||
Type: `'start' | 'end'` | ||
Default value: `start` | ||
It controls where the backlinks are displayed â to the `'start'` or `'end'` of the footnotes. | ||
### `backlinkSymbol` | ||
Type: `string` | ||
Default value: `â` | ||
It is the symbol that you will see at the start of the backlinks part of each footnote. | ||
> [!NOTE] | ||
> If you have just one reference to a footnote, then this symbol is a link that points to that reference. If you have multiple reference to a footnote then initially this symbol is just text but when you click on any of its references, this symbol will turn into a link pointing back to that specific reference that you clicked. | ||
### `jumpTexts` | ||
Type: | ||
``` | ||
{ | ||
jumpUp?: string; | ||
jumpBackUp?: string; | ||
jumpUpTo?: string; | ||
} | ||
``` | ||
Default value: | ||
```js | ||
{ | ||
jumpUp: 'Jump up', | ||
jumpBackUp: 'Jump back up', | ||
jumpUpTo: 'Jump up to: ', | ||
} | ||
``` | ||
The `jumpUp` and `jumpBackUp` property values are used for showing tooltip text and `aria-label`(useful for screen reader users) for the backlink symbol. | ||
The `jumpUpTo` is solely for screen reader users to give them some context to the backlink superscripts(which appear if you have multiple references to this footnote) that holds backlinks next to the backlink symbol. | ||
You might want to translate the English text values for these properties if your content is in a different language. | ||
### `getBacklinkIdentifier` | ||
Type: `(n: number) => string` | ||
Default Behavior: It uses [`numberFormat`](#numberformat) option to determine the format of the each individual backlink superscripts which exist next to [backlink symbol](#backlinksymbol). | ||
Here `n` is a natural number. `1`, `2` and so on relates to the first, second and so on backlink superscripts. The returned string is placed in the corresponding position. | ||
Following is an example that uses English alphabets instead of numbers for backlink superscripts. | ||
<details> | ||
<summary>Click to see the example</summary> | ||
 | ||
Code: | ||
```html | ||
<p> | ||
Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum | ||
sint consectetur cupidatat.<sup data-padatika>notes:example1</sup> Lorem ipsum | ||
dolor sit amet, qui minim labore adipisicing minim sint cillum sint | ||
consectetur cupidatat.<sup data-padatika>notes:example2</sup> | ||
</p> | ||
<script type="module"> | ||
import padatika from 'https://cdn.jsdelivr.net/npm/padatika@0.1.0/dist/index.js'; | ||
<p> | ||
Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum | ||
sint consectetur cupidatat.<sup data-padatika>notes:example3</sup> | ||
</p> | ||
padatika( | ||
{ notes: 'N', refs: 'R' }, | ||
{ | ||
getBacklinkIdentifier: (n) => { | ||
return 'abcdefghijklmnopqrstuvwxyz'[n - 1]; | ||
}, | ||
}, | ||
); | ||
</script> | ||
I like cats.<sup data-fnref>notes:cats</sup> | ||
I like dogs.<sup data-fnref>notes:dogs</sup> | ||
The kitten is calling her mom.<sup data-fnref>notes:cats</sup> | ||
I smell something.<sup data-fnref>refs:something</sup> | ||
<h2 id="notes">Notes</h2> | ||
<ul> | ||
<li>[example1] This is my first example footnote.</li> | ||
<li>[example2] This is my second example footnote.</li> | ||
<li>[example3] This is my third example footnote.</li> | ||
<li>[cats] meow meow</li> | ||
<li>[dogs] woof woof</li> | ||
</ul> | ||
<h2 id="refs">References</h2> | ||
<ul> | ||
<li>[something] dog ðĐ</li> | ||
</ul> | ||
``` | ||
It's time to reveal the meaning of the empty string passed to `notes` in the object passed to `initPadatika` call. It has two effects: | ||
</details> | ||
- In the output you don't see any category indicator at the start of your references because we set it to an empty string. | ||
- You don't need to write the category name for this references to this category of footenotes. But if you want you can still do it for explicitness. | ||
### `getListStyleTypeStr` | ||
So we can rewrite the previous references like below: | ||
Type: `(formattedNum: string) => string` | ||
Default value: ``(formattedNum: string) => `${formattedNum}. ` `` | ||
This option is used for determininig the footnotes numbering format. The function takes in the formatted number(which depends on the [`numberFormat`](#numberformat) option) and should return a string based on it. | ||
<details> | ||
<summary>Click to see an example</summary> | ||
 | ||
Code: | ||
```html | ||
<p> | ||
Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum | ||
sint consectetur cupidatat.<sup data-padatika>example1</sup> Lorem ipsum dolor | ||
sit amet, qui minim labore adipisicing minim sint cillum sint consectetur | ||
cupidatat.<sup data-padatika>example2</sup> | ||
</p> | ||
<script type="module"> | ||
import padatika from 'https://cdn.jsdelivr.net/npm/padatika@0.1.0/dist/index.js'; | ||
<p> | ||
Lorem ipsum dolor sit amet, qui minim labore adipisicing minim sint cillum | ||
sint consectetur cupidatat.<sup data-padatika>example3</sup> | ||
</p> | ||
padatika( | ||
{ notes: 'N' }, | ||
{ | ||
getListStyleTypeStr: (formattedNum) => `[${formattedNum}] `, | ||
}, | ||
); | ||
</script> | ||
I like cats.<sup data-fnref>notes:cats</sup> | ||
<h2 id="notes">Notes</h2> | ||
<ul> | ||
<li>[cats] meow meow</li> | ||
</ul> | ||
``` | ||
On the otherhand if you pass something to the value of `notes`, for example `N`, it would cause the following effects: | ||
</details> | ||
- You must specify the category name in your references. This true even you have just one category. For example you would have to use `<sup data-padatika>notes:example3</sup>` instead of `<sup data-padatika>example3</sup>`. | ||
- In the output you will see the category indicator `N` before your reference numbers. So the text in the superscript will be something like `[N 3]`. | ||
### `ignoreIndicatorOfFirstCategory` | ||
In the first object passed to `initPadatika`, more than one category key can't have empty string or same string as its value. This value represents the category indicator in the references. Without category indicator, the numbers in references would conflict with other categories. This is why the values must be unique. | ||
Type: `boolean` | ||
Default value: `true` | ||
In controls if the category indicator is displayed or not for references that targets the footnotes of the first category in document order. So if you just one category then by default in the references you will see just numbers wrapped in square brackets. If you have another category of footnotes then the references of the second category will by default start with its category indicator and end with its number with a space in between, wrapped in square brackets. | ||
### `ignoreIndicatorOfCategory` | ||
Type: `string` | ||
Default value: `undefined` | ||
This option allows you to provide category name to ignore its indicator in corresponding references. | ||
> [!NOTE] | ||
> If `ignoreIndicatorOfFirstCategory` is `true` and `ignoreIndicatorOfCategory` has a category name, then `ignoreIndicatorOfFirstCategory` is has no effect. | ||
### `enableBrackets` | ||
Type: `boolean` | ||
Default value: `true` | ||
This is to turn on/off the brackets around footnote references. | ||
### `sep` | ||
Type: `string` | ||
Default value: `' '`(a space) | ||
This option allows you to customize the separator between category indicator and reference number in your footnote references. | ||
### `targetedBacklinkClassName` | ||
Type: `string` | ||
Default value: `'targeted-backlink'` | ||
If a footnote has multiple references and you clink on one of them then the anchor of the corresponding backlink superscript will get its class name from this option. The class name from that anchor is removed if you click on another link generated by Padatika. | ||
### `backlinksWrapperClassName` | ||
Type: `string` | ||
Default value: `'backlinks-wrapper'` | ||
There exists a wrapper `<span>` element around the backlinks part of each footnote. This element gets its class name from this option. | ||
## ðĪ Frequently Asked Questions <sub>(that no one asked yet)</sub> | ||
If you have any other question related to Padatika than the following, feel free to open an issue. | ||
### What does "Padatika" mean? | ||
It is the transliteration of the Bangla word "āĶŠāĶūāĶĶāĶā§āĶāĶū" which means footnote. | ||
### Can Padatika can show the footnote content in tooltip when hovering over the references? | ||
No, I have no plans to implement this in Padatika because it's impossible to implement it in just a few lines of code. I believe it's best to use a dedicated solution like [Tippy.js](https://atomiks.github.io/tippyjs/) for this, which appears to be a fantastic library. I haven't yet had the opportunity to experiment with it myself. If you do, I would greatly appreciate an article where you share your experience. | ||
### How to use Padatika with a bundler? | ||
You can install it using your favorite node package manager to do this. Just note that it exports a function as a default export, so you can import using any name. | ||
### Does Padatika offer styles? | ||
It has very minimal CSS implemented with JS that I find unavoidable for good first experience. Except that I've no plan to prescribe styles to let the users be creative with their own styles. | ||
### Writing the markup for a footnote reference (`<sup data-fnref>category_id:footnote_name</sup>`) can be quite cumbersome. Is there a way to achieve the same purpose without having to type so much? | ||
As a lazy person, I can relate to this. Unfortunately I can't make it shorter than this in a good way with Padatika. | ||
However I managed to overcome it in a easy way in my [personal website](https://ashutoshbw.github.io/). I built my site using [Zola](https://www.getzola.org/). It transforms markdown to HTML and allows you do simple replacements on those HTML files efficiently. Here I replace `[<em>` with `<sup data-fnref>` and `</em>]` with `</sup>`. So in the markdown I can use the format `[_category_id:footnote_name_]`! | ||
Even if you don't use Zola, you can use your editor to do such replacements or create your own little snippet for your editor that you can invoke with minimal amount typing. | ||
### Footnotes without a name, with an invalid name, or with a duplicate name do not appear on the rendered web page. Is that okay? | ||
Yes. It is designed this way give you a clean result. But if you open your browser console, you will get warnings or errors for them to help you detect them. | ||
## ð Acknowledgement | ||
I stole the essence of footnote backlinks from Wikipedia. |
Sorry, the diff of this file is not supported yet
118599
15
59
531
6