Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
A
a-doc-editor
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Ramdayal Munda
a-doc-editor
Commits
71818282
Commit
71818282
authored
Jan 16, 2024
by
ramdayalmunda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
changes for pdf
parent
940f5e70
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
226 additions
and
70 deletions
+226
-70
a-doc-editor.css
dist/assets/a-doc-editor.css
+3
-0
a-doc-editor.js
dist/assets/a-doc-editor.js
+220
-69
script.js
dist/script.js
+3
-1
No files found.
dist/assets/a-doc-editor.css
View file @
71818282
...
...
@@ -12,6 +12,9 @@
hidden
{
display
:
none
;
}
canvas
:focus-visible
{
outline
:
unset
;
}
.header
{
position
:
relative
;
...
...
dist/assets/a-doc-editor.js
View file @
71818282
let
isModule
=
(
typeof
module
!=
'undefined'
)
?
true
:
false
if
(
!
isModule
)
console
.
log
(
'Browser Environment'
)
var
ADocEditor
=
function
(
customConfig
)
{
var
container
,
counter
=
0
,
shadow
,
pxMmRatio
,
canvasPxMmRatio
,
config
,
htmlStr
,
htmlTag
,
htmlObj
=
{},
fontList
=
[],
headerToolbar
=
[];
var
container
,
counter
=
0
,
shadow
,
pxMmRatio
,
config
,
htmlStr
,
htmlTag
,
htmlObj
=
{},
fontList
=
[],
headerToolbar
=
[];
const
mmPtRatio
=
254
/
720
;
// this is used for font size
var
paperSizes
=
{
"A4"
:
{
mmWidth
:
210
,
mmHeight
:
297
},
}
...
...
@@ -13,10 +14,10 @@ var ADocEditor = function (customConfig) {
background
:
"#fff"
,
margin
:
15
,
// mm
border
:
""
,
tabWidth
:
2
0
,
// mm
tabWidth
:
1
0
,
// mm
},
style
:
{
fontSize
:
1
0
,
// this is in
mm
fontSize
:
1
1
,
// this is in pt // 1pt = 1/72 inch // 1pt = 254/72
mm
fontFamily
:
'Calibri'
,
bold
:
false
,
italic
:
false
,
...
...
@@ -68,6 +69,7 @@ var ADocEditor = function (customConfig) {
<div adc-type="sub-menu" adc-action="new-file">New</div>
<div adc-type="sub-menu" adc-action="open-file">Open</div>
<div adc-type="sub-menu" adc-action="save-file">Save</div>
<div adc-type="sub-menu" adc-action="print-file">Print</div>
</div>
</div>
<div class="item" adc-target="help-menu" adc-type="menu-item">
...
...
@@ -247,6 +249,9 @@ var ADocEditor = function (customConfig) {
})
shadow
.
querySelector
(
'[adc-action="open-file"]'
)
.
addEventListener
(
'click'
,
()
=>
{
openFileInput
.
click
()
})
shadow
.
querySelector
(
'[adc-action="print-file"]'
)
.
addEventListener
(
'click'
,
printDoc
)
})()
reConfigure
(
customConfig
)
...
...
@@ -417,7 +422,7 @@ var ADocEditor = function (customConfig) {
lineObj
.
plainContent
=
dataBlock
.
plainContent
.
slice
(
lineObj
.
charStartIndex
,
lineObj
.
charEndIndex
+
1
)
// there is chance that the last line is not at the width// so we need to handle the last line separately
if
(
lineObj
.
charEndIndex
<=
dataBlock
.
plainContent
.
length
)
{
lineObj
.
charEndIndex
=
dataBlock
.
plainContent
.
length
-
1
lineObj
.
charEndIndex
=
dataBlock
.
plainContent
.
length
}
lineObj
.
plainContent
=
dataBlock
.
plainContent
.
slice
(
lineObj
.
charStartIndex
,
lineObj
.
charEndIndex
)
...
...
@@ -430,24 +435,45 @@ var ADocEditor = function (customConfig) {
}
function
renderLines
()
{
let
maxHeight
=
config
.
pageSetup
.
pxHeight
-
config
.
format
.
margin
*
pxMmRatio
*
2
let
pageIndex
=
0
let
x
=
0
,
y
=
config
.
format
.
margin
*
pxMmRatio
;
for
(
let
l
=
0
;
l
<
lines
.
length
;
l
++
)
{
let
setData
=
dataList
[
lines
[
l
].
dataIndex
]
let
ctx
=
pageList
[
0
].
el
.
getContext
(
'2d'
,
{
willReadFrequently
:
true
})
let
ctx
=
pageList
[
pageIndex
].
el
.
getContext
(
'2d'
,
{
willReadFrequently
:
true
})
x
=
config
.
format
.
margin
*
pxMmRatio
x
+=
lines
[
l
].
tabWidth
y
=
y
+
(
lines
[
l
].
maxFontSize
*
pxMmRatio
)
y
=
y
+
(
lines
[
l
].
maxFontSize
*
pxMmRatio
*
mmPtRatio
)
lines
[
l
].
y
=
y
// check if the line is to be written on the next page
if
(
maxHeight
<
y
)
{
pageIndex
++
if
(
!
pageList
?.[
pageIndex
])
{
pageList
[
pageIndex
]
=
{
id
:
++
counter
,
el
:
createNewPage
(),
dataIndex
:
lines
[
l
].
dataIndex
}
shadow
.
querySelector
(
'[adc="page-list"]'
).
append
(
pageList
[
pageIndex
].
el
)
}
ctx
=
pageList
[
pageIndex
].
el
.
getContext
(
'2d'
,
{
willReadFrequently
:
true
})
y
=
config
.
format
.
margin
*
pxMmRatio
+
(
lines
[
l
].
maxFontSize
*
pxMmRatio
*
mmPtRatio
);
lastFocussedPage
=
pageList
[
pageIndex
].
el
caretData
.
blink
=
false
focusOnPage
({
scroll
:
true
})
}
lines
[
l
].
pageIndex
=
pageIndex
ctx
.
save
()
// this is to render the numbering and bullets etc
if
(
lines
[
l
].
dataType
==
1
)
{
ctx
.
save
()
ctx
.
font
=
`
${
setData
.
style
.
fontSize
*
pxMmRatio
}
px
${
setData
.
style
.
fontFamily
}
`
ctx
.
font
=
`
${
setData
.
style
.
fontSize
*
pxMmRatio
*
mmPtRatio
}
px
${
setData
.
style
.
fontFamily
}
`
ctx
.
fillStyle
=
`
${
setData
.
style
.
fontColor
}
`
let
label
=
getLabel
(
lines
[
l
].
dataIndex
)
let
labelWidth
=
ctx
.
measureText
(
label
).
width
labelWidth
+=
pxMmRatio
*
5
labelWidth
+=
mmPtRatio
*
pxMmRatio
*
5
lines
[
l
].
labelWidth
=
labelWidth
ctx
.
fillText
(
label
,
x
-
labelWidth
,
y
)
ctx
.
restore
()
}
...
...
@@ -459,7 +485,7 @@ var ADocEditor = function (customConfig) {
if
(
char
)
{
let
style
=
setData
.
formatedText
[
c
]
ctx
.
save
()
ctx
.
font
=
`
${
style
?.
bold
?
'bold '
:
''
}
$
{
style
?.
italic
?
'italic '
:
''
}
$
{
style
.
fontSize
*
pxMmRatio
}
px
$
{
style
.
fontFamily
}
`
ctx
.
font
=
`
${
style
?.
bold
?
'bold '
:
''
}
$
{
style
?.
italic
?
'italic '
:
''
}
$
{
style
.
fontSize
*
pxMmRatio
*
mmPtRatio
}
px
$
{
style
.
fontFamily
}
`
ctx.fillStyle = `
$
{
style
?.
fontColor
}
`
ctx.fillText(char, x, y)
setData.formatedText[c].x = x
...
...
@@ -476,63 +502,12 @@ var ADocEditor = function (customConfig) {
return
}
function getLabel(dataIndex) {
let label = "x."
if (dataList[dataIndex].listStyle == 0) { // 1. a. i.
let tabCount = dataList[dataIndex].tabCount
tabCount = tabCount ? tabCount : 0
if (tabCount % 3 == 0) label = `
$
{
dataList
[
dataIndex
].
listItemNumber
}.
`
else if (tabCount % 3 == 1) label = `
$
{
convertToLetter
(
dataList
[
dataIndex
].
listItemNumber
)}.
`
else label = `
$
{
convertToRoman
(
dataList
[
dataIndex
].
listItemNumber
).
toLowerCase
()}.
`
}
else if (dataList[dataIndex].listStyle == 1) { // >
label = `
>
`
}
function convertToLetter(num) {
num = (num - 1).toString(26)
let label = ""
for (let i = 0; i < num.length; i++) label += letters[num[i]]
return label
}
function convertToRoman(num) {
let result = '';
let divisor = 1000;
for (let i = 3; i >= 0; i--) {
const digit = Math.floor(num / divisor);
num %= divisor;
divisor /= 10;
if (digit > 0) {
if (digit === 9) {
result += romanNumerals[i][3];
} else if (digit >= 5) {
result += romanNumerals[i][2];
result += romanNumerals[i][0].repeat(digit - 5);
} else if (digit === 4) {
result += romanNumerals[i][1];
} else {
result += romanNumerals[i][0].repeat(digit);
}
}
}
return result;
}
return label
}
function getCharacterWidth(char, style) {
let canvas = pageList[0].el
let ctx = canvas.getContext('2d', { willReadFrequently: true })
ctx.save()
ctx.font = `
$
{
style
?.
bold
?
'bold '
:
''
}
$
{
style
?.
italic
?
'italic '
:
''
}
$
{
style
.
fontSize
*
pxMmRatio
}
px
$
{
style
.
fontFamily
}
`
ctx.font = `
$
{
style
?.
bold
?
'bold '
:
''
}
$
{
style
?.
italic
?
'italic '
:
''
}
$
{
style
.
fontSize
*
pxMmRatio
*
mmPtRatio
}
px
$
{
style
.
fontFamily
}
`
ctx.fillStyle = `
$
{
style
?.
fontColor
}
`
let width = ctx.measureText(char).width
ctx.restore()
...
...
@@ -680,7 +655,7 @@ var ADocEditor = function (customConfig) {
let found = false
for (let l = 0; l < lines.length; l++) {
if ((cursor.y <= lines[l].y) && (cursor.y >= (lines[l].maxFontSize * pxMmRatio))) {
if ((cursor.y <= lines[l].y) && (cursor.y >= (lines[l].maxFontSize * pxMmRatio
* mmPtRatio
))) {
let dataSet = dataList[lines[l].dataIndex]
for (let c = lines[l].charStartIndex; c <= lines[l].charEndIndex; c++) {
if ((cursor.x >= dataSet.formatedText[c].x) && (cursor.x <= (dataSet.formatedText[c].width + dataSet.formatedText[c].x))) {
...
...
@@ -730,6 +705,58 @@ var ADocEditor = function (customConfig) {
}
}
function getLabel(dataIndex) {
let label = "x."
if (dataList[dataIndex].listStyle == 0) { // 1. a. i.
let tabCount = dataList[dataIndex].tabCount
tabCount = tabCount ? tabCount : 0
if (tabCount % 3 == 0) label = `
$
{
dataList
[
dataIndex
].
listItemNumber
}.
`
else if (tabCount % 3 == 1) label = `
$
{
convertToLetter
(
dataList
[
dataIndex
].
listItemNumber
)}.
`
else label = `
$
{
convertToRoman
(
dataList
[
dataIndex
].
listItemNumber
).
toLowerCase
()}.
`
}
else if (dataList[dataIndex].listStyle == 1) { // >
label = `
>
`
}
function convertToLetter(num) {
num = (num - 1).toString(26)
let label = ""
for (let i = 0; i < num.length; i++) label += letters[num[i]]
return label
}
function convertToRoman(num) {
let result = '';
let divisor = 1000;
for (let i = 3; i >= 0; i--) {
const digit = Math.floor(num / divisor);
num %= divisor;
divisor /= 10;
if (digit > 0) {
if (digit === 9) {
result += romanNumerals[i][3];
} else if (digit >= 5) {
result += romanNumerals[i][2];
result += romanNumerals[i][0].repeat(digit - 5);
} else if (digit === 4) {
result += romanNumerals[i][1];
} else {
result += romanNumerals[i][0].repeat(digit);
}
}
}
return result;
}
return label
}
function changeListStyle() {
let activeDataIndex = dataList.findIndex(item => item.id == caretData.activeData.id)
let d = activeDataIndex - 1
...
...
@@ -762,6 +789,12 @@ var ADocEditor = function (customConfig) {
format = format[format.length - 1]
fontObj.paths.push(paths[i])
linkString += `
url
(
$
{
paths
[
i
]})
format
(
"${format == 'ttf' ? 'truetype' : format}"
)
$
{(
i
>=
paths
.
length
-
1
)
?
''
:
',
\
n'
}
`
if (format == 'ttf') {
fetch(paths[i])
.then(response => response.arrayBuffer())
.then(fontBytes => { fontObj.fontBytes = fontBytes })
}
}
const customFont = new FontFace(`
$
{
name
}
`, `
$
{
linkString
}
`);
customFont.load()
...
...
@@ -820,12 +853,18 @@ var ADocEditor = function (customConfig) {
if (item.getAttribute('adc') == targetId) item.classList.toggle('show')
else item.classList.remove('show')
})
}
function renderCaret(toLoop) {
clearTimeout(caretData.timeout)
let ctx = pageList[0].el.getContext('2d', { willReadFrequently: true })
let dataIndex = dataList.findIndex(item => item.id == caretData.activeData.id)
let lineIndex = lines.findIndex(item => item.dataIndex == dataIndex && caretData.index <= item.charEndIndex)
let lineObj = lines[lineIndex]
let prevLine = lines[lineIndex - 1]
let ctx = pageList[lineObj.pageIndex].el.getContext('2d', { willReadFrequently: true })
ctx.save()
if (caretData.previousCaret) {
ctx.putImageData(caretData.previousCaret.imageData, caretData.previousCaret.x, caretData.previousCaret.y);
...
...
@@ -836,16 +875,21 @@ var ADocEditor = function (customConfig) {
let lineObj = lines.find(item => item.dataIndex == dataIndex && caretData.index >= item.charStartIndex)
let x = (config.format.margin * pxMmRatio) + lineObj.tabWidth
let y = (config.format.margin) * pxMmRatio
let height = caretData.style.fontSize * pxMmRatio * 5 / 4
let height = caretData.style.fontSize * pxMmRatio *
mmPtRatio *
5 / 4
let width = height / 10
let charData = caretData.activeData.formatedText[caretData.index - 1]
if (lineObj) {
x = (charData ? (charData.x + charData.width) : x)
if (charData) {
y = charData.y - (caretData.style.fontSize * pxMmRatio)
y = charData.y - (caretData.style.fontSize * pxMmRatio
* mmPtRatio
)
} else {
y = lineObj.y - (lineObj.maxFontSize * pxMmRatio)
if (prevLine && prevLine.pageIndex != lineObj.pageIndex) {
y = (config.format.margin) * pxMmRatio
}
else {
y = lineObj.y - (lineObj.maxFontSize * pxMmRatio * mmPtRatio)
}
}
}
...
...
@@ -866,6 +910,13 @@ var ADocEditor = function (customConfig) {
caretData.blink = false
}
let thisPage = pageList[lineObj.pageIndex].el
if (thisPage != focussedPage) {
lastFocussedPage = thisPage
focussedPage = thisPage
focusOnPage()
}
ctx.restore()
if (toLoop) {
caretData.timeout = setTimeout(() => {
...
...
@@ -874,13 +925,16 @@ var ADocEditor = function (customConfig) {
}
return
}
function focusOnPage() {
function focusOnPage(
options = { scroll: false }
) {
caretData.blink = false
if (!lastFocussedPage) lastFocussedPage = pageList[0].el
if (lastFocussedPage) {
const scrollTop = pageScrollingDiv.scrollTop
lastFocussedPage.focus()
lastFocussedPage.focus()
; // comment this
pageScrollingDiv.scrollTop = scrollTop
if (options.scroll) {
lastFocussedPage.scrollIntoView({ behavior: "smooth" })
}
}
}
...
...
@@ -931,11 +985,13 @@ var ADocEditor = function (customConfig) {
function compressDocJSON() {
let activeDataIndex = dataList.findIndex(item => item.id == caretData.activeData.id)
let returnObj = {
lines: JSON.parse(JSON.stringify(lines)), // this is not required by the user.
pxMmRatio: pxMmRatio,
config: JSON.parse(JSON.stringify(config)),
content: JSON.parse(JSON.stringify(dataList)),
caretData: JSON.parse(JSON.stringify(caretData))
}
delete returnObj.caretData.activeData
delete returnObj.caretData.previousCaret
returnObj.caretData.activeDataIndex = activeDataIndex
...
...
@@ -956,6 +1012,100 @@ var ADocEditor = function (customConfig) {
reRenderCanvas()
}
// http://localhost:3910/assets/fonts/calibri-regular.woff2
async function printDoc() {
// pdf dimention in pdf-lib is based on 'pt' or 'points' by default.
// 1pt = 1/72 inch
const { PDFDocument, rgb } = PDFLib
const pdfDoc = await PDFDocument.create();
pdfDoc.registerFontkit(fontkit)
let embeddedFonts = {}
let page;
let pageHeight = config.pageSetup.mmHeight / mmPtRatio
let pageWidth = config.pageSetup.mmWidth / mmPtRatio
let x = 0, y = config.format.margin * pxMmRatio;
for (let l = 0; l < lines.length; l++) {
let dataSet = dataList[lines[l].dataIndex]
if (lines?.[l - 1]?.pageIndex != lines[l].pageIndex) {
page = pdfDoc.addPage([pageWidth, pageHeight]);
}
x = config.format.margin * pxMmRatio
x += lines[l].tabWidth
// this is to render the numbering and bullets etc
if (lines[l].dataType == 1) {
let fontObj = fontList.find(item => item.name == dataSet.style.fontFamily)
let font = embeddedFonts[fontObj.name]
if (!font) {
const fontBytes = fontObj.fontBytes
font = await pdfDoc.embedFont(fontBytes);
embeddedFonts[fontObj.name] = font
}
let label = getLabel(lines[l].dataIndex)
let width = lines[l].labelWidth
x = (x - width) / (pxMmRatio * mmPtRatio)
y = pageHeight - lines[l].y / (pxMmRatio * mmPtRatio)
page.drawText(label, {
x, y, font,
size: dataSet.style.fontSize,
color: rgb(...getRgb(dataSet.style.fontColor))
});
}
for (let c = lines[l].charStartIndex; c < lines[l].charEndIndex; c++) {
let fontObj = fontList.find(item => item.name == dataSet.formatedText[c].fontFamily)
let font = embeddedFonts[fontObj.name]
if (!font) {
const fontBytes = fontObj.fontBytes
font = await pdfDoc.embedFont(fontBytes);
embeddedFonts[fontObj.name] = font
}
x = dataSet.formatedText[c].x / (pxMmRatio * mmPtRatio); // X-coordinate
y = pageHeight - dataSet.formatedText[c].y / (pxMmRatio * mmPtRatio); // Y-coordinate
page.drawText(dataSet.plainContent[c], {
x, y, font,
size: dataSet.formatedText[c].fontSize,
color: rgb(...getRgb(dataSet.formatedText[c].fontColor))
});
}
// Set the font and size
// Embed the custom font
}
function getRgb(hex) {
let rgbArr = [0, 0, 0]
if (hex.length == 7) {
rgbArr = [parseInt(hex.slice(1, 3), 16) / 255, parseInt(hex.slice(3, 5), 16) / 255, parseInt(hex.slice(5, 7), 16) / 255]
} else if (hex.length == 4) {
rgbArr = [parseInt(hex.slice(1, 2), 16) / 15, parseInt(hex.slice(2, 3), 16) / 15, parseInt(hex.slice(3, 4), 16) / 15]
}
return rgbArr
}
// Save the modified PDF
const pdfBytes = await pdfDoc.save();
// For demonstration purposes, you can download the PDF
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
const link = shadow.querySelector('[adc="download-link"]');
link.href = URL.createObjectURL(blob);
link.download = '1_from_editor.pdf';
link.click();
}
var returnObj = {
getDocumentData() {
return compressDocJSON()
...
...
@@ -972,6 +1122,7 @@ var ADocEditor = function (customConfig) {
console.log(compressDocJSON())
},
focusOnPage,
printDoc,
}
initialize()
...
...
dist/script.js
View file @
71818282
...
...
@@ -13,7 +13,9 @@ var tempDocData = [
var
editor
=
new
ADocEditor
({
container
:
document
.
getElementById
(
"user-container-for-editor"
)
})
editor
.
focusOnPage
()
setTimeout
(
()
=>
{
editor
.
focusOnPage
()
},
100
)
var
extractedData
=
null
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment