diff --git a/README.md b/README.md index 8569f9f..f5826cb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,28 @@ # Pdfbox -BaseX (10+) interface to [Pdfbox](https://pdfbox.apache.org/) 3 +BaseX (10+) interface to [Pdfbox](https://pdfbox.apache.org/) version 3 +## Features +* read page count +* read outline +* read pagelabels +* read page text +* save pdf page range to new pdf +* save pdf page as image +Uses +* https://github.com/blikblum/slick-router#readme +* https://dev.to/blikblum/slick-router-a-powerful-router-for-web-components-3fck + +## Sync +``` +cd C:\Users\mrwhe\git\expkg-zone58\pdfbox\src\webapp\pdf + +c:\DeltaCopy\rsync -rlptz --progress --exclude=.git --exclude=.vscode . andy@localhost::basexserv/ +``` +## Jars +* fontbox-3.0.2.jar +* pdfbox-3.0.2.jar +* pdfbox-io-3.0.2.jar +* commons-logging-1.3.1.jar + +3.6 mb \ No newline at end of file diff --git a/docs/pdfbox.xqbk b/docs/pdfbox.xqbk index 6acf97b..9909d4d 100644 --- a/docs/pdfbox.xqbk +++ b/docs/pdfbox.xqbk @@ -1 +1 @@ -{"cells":[{"kind":1,"language":"markdown","value":"# PDFBox3 \r\nA BaseX 10+ interface to Apache PDFBox® library version 3 \r\n## Apache PDFBox® - A Java PDF Library\r\n\r\nThe Apache PDFBox® library is an open source Java tool for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents. Apache PDFBox also includes several command-line utilities. Apache PDFBox is published under the Apache License v2.0.\r\nhttps://pdfbox.apache.org/"},{"kind":1,"language":"markdown","value":"It comes with the useful PDF debug tool `java -jar debugger-app-3.0.1.jar`"},{"kind":1,"language":"markdown","value":"## Set up XQuery context for following code..."},{"kind":2,"language":"xquery","value":"(:<:)(: XQuery Context :)\r\nimport module namespace pdfbox = \"urn:expkg-zone58:pdfbox3\" at \"../src/lib/pdfbox3.xqm\";\r\nimport module namespace bookpages = 'urn:bookpages' at \"../src/lib/bookpages.xqm\";\r\nimport module namespace pdfscrape = 'urn:pdfscrape' at \"../src/lib/pdfscrape.xqm\";\r\nimport module namespace config = 'urn:abc-clio:config' at 'C:\\Users\\mrwhe\\git\\bloomsbury\\content-architecture\\xquery\\ABC-CLIO/lib/abc-config.xqm';\r\n\r\ndeclare variable $samples:= map{\r\n \"climate\": \"drop-01d\\set\\2-6-1\\A5579C_1\\271989---Book_File-Web_PDF_9798400627484_486728.pdf\",\r\n \"women\": \"drop-01d\\set\\2-6-1\\A6229C_1\\257334---Book_File-Web_PDF_9798216172628_486742.pdf\",\r\n \"genocide\": \"drop1-pdf\\GR2967-TRD\\272791---Book_File-Web_PDF_9798400640216_486366.pdf\",\r\n \"world\": \"drop-01c\\gpg-book\\2-6\\A3506C-TRD\\256186---Book_File-Web_PDF_9798216038955_486148.pdf\"\r\n};\r\ndeclare variable $PDF:= (: $samples?women=>file:resolve-path($config:data) :)\r\n\"C:\\Users\\mrwhe\\git\\bloomsbury\\content-architecture\\xquery\\ABC-CLIO\\data\\drop-01e\\set\\2-6-1\\A5690C_1\\257107---Book_File-Web_PDF_9798400691218_486731.pdf\";"},{"kind":1,"language":"markdown","value":" ## Check pdfbox version"},{"kind":2,"language":"xquery","value":"pdfbox:version()"},{"kind":1,"language":"markdown","value":"PDF specification version used by document"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:pdfVersion()"},{"kind":1,"language":"markdown","value":"# Page count for PDF"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:page-count()"},{"kind":1,"language":"markdown","value":"# save range to new pdf"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:extract(2,12,\"c:\\tmp\\a.pdf\")"},{"kind":1,"language":"markdown","value":"## Outline / bookmarks"},{"kind":1,"language":"markdown","value":"### sequence of maps"},{"kind":2,"language":"xquery","value":"\r\npdfbox:open($PDF)=>pdfbox:outline()"},{"kind":1,"language":"markdown","value":"XML"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:outline()=>pdfbox:outline-xml()"},{"kind":1,"language":"markdown","value":"## Page labels"},{"kind":2,"language":"xquery","value":"\r\npdfbox:open($PDF)=>pdfbox:pageLabels()"},{"kind":1,"language":"markdown","value":"# getText from page index"},{"kind":2,"language":"xquery","value":"let $doc:=pdfbox:open($PDF)\r\nreturn pdfbox:getText($doc,56)"},{"kind":1,"language":"markdown","value":"# Page scraping"},{"kind":1,"language":"markdown","value":"## pdf scrape text analysis"},{"kind":2,"language":"xquery","value":"let $doc:=pdfbox:open($PDF)\r\nreturn pdfscrape:page-report($doc)\r\n"},{"kind":1,"language":"markdown","value":"## Inverted pageno map"},{"kind":2,"language":"xquery","value":"let $doc:=pdfbox:open($PDF)\r\nreturn pdfscrape:page-report($doc)=>pdfscrape:inverted-map()"},{"kind":1,"language":"markdown","value":"# Save images"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)\r\n=> pdfbox:pageAsImage(0,0.25)\r\n=> pdfbox:imageSave(\"c:\\tmp\\page0.gif\",\"gif\")"},{"kind":1,"language":"markdown","value":"## report"},{"kind":2,"language":"xquery","value":"declare variable $a:=file:resolve-path(\"../data/1e/\",file:base-dir());\r\n\r\nfor $f in file:list($a,true(),\"*.pdf\") \r\nwhere not(contains($f,\"outputs\"))\r\nlet $doc:=pdfbox:open(file:resolve-path($f,$a))\r\n(: let $outline:=pdfbox:outline($doc) :)\r\nlet $count:=pdfbox:page-count($doc)\r\norder by $count \r\nreturn ``[`{$f}`: `{ $count }`]``"}]} \ No newline at end of file +{"cells":[{"kind":1,"language":"markdown","value":"# PDFBox3 \r\nA BaseX 10+ interface to Apache PDFBox® library version 3 \r\n## Apache PDFBox® - A Java PDF Library\r\n\r\nThe Apache PDFBox® library is an open source Java tool for working with PDF documents. This project allows creation of new PDF documents, manipulation of existing documents and the ability to extract content from documents. Apache PDFBox also includes several command-line utilities. Apache PDFBox is published under the Apache License v2.0.\r\nhttps://pdfbox.apache.org/"},{"kind":1,"language":"markdown","value":"It comes with the useful PDF debug tool `java -jar debugger-app-3.0.2.jar`"},{"kind":1,"language":"markdown","value":"## Set up XQuery context for following code..."},{"kind":2,"language":"xquery","value":"(:<:)(: XQuery Context :)\r\nimport module namespace pdfbox = \"urn:expkg-zone58:pdfbox3\" at \"../src/lib/pdfbox3.xqm\";\r\nimport module namespace bookpages = 'urn:bookpages' at \"../src/lib/bookpages.xqm\";\r\nimport module namespace pdfscrape = 'urn:pdfscrape' at \"../src/lib/pdfscrape.xqm\";\r\nimport module namespace config = 'urn:abc-clio:config' at 'C:\\Users\\mrwhe\\git\\bloomsbury\\content-architecture\\xquery\\ABC-CLIO/lib/abc-config.xqm';\r\n\r\ndeclare variable $samples:= map{\r\n \"climate\": \"drop-01d\\set\\2-6-1\\A5579C_1\\271989---Book_File-Web_PDF_9798400627484_486728.pdf\",\r\n \"women\": \"drop-01d\\set\\2-6-1\\A6229C_1\\257334---Book_File-Web_PDF_9798216172628_486742.pdf\",\r\n \"genocide\": \"drop1-pdf\\GR2967-TRD\\272791---Book_File-Web_PDF_9798400640216_486366.pdf\",\r\n \"world\": \"drop-01c\\gpg-book\\2-6\\A3506C-TRD\\256186---Book_File-Web_PDF_9798216038955_486148.pdf\"\r\n};\r\ndeclare variable $PDF:= (: $samples?women=>file:resolve-path($config:data) :)\r\n\"C:\\Users\\mrwhe\\git\\bloomsbury\\content-architecture\\xquery\\ABC-CLIO\\data\\drop-01e\\set\\2-6-1\\A5690C_1\\257107---Book_File-Web_PDF_9798400691218_486731.pdf\";"},{"kind":1,"language":"markdown","value":" ## Check pdfbox version"},{"kind":2,"language":"xquery","value":"pdfbox:version()"},{"kind":1,"language":"markdown","value":"PDF specification version used by document"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:pdfVersion()"},{"kind":1,"language":"markdown","value":"# Page count for PDF"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:page-count()"},{"kind":1,"language":"markdown","value":"# save range to new pdf"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:extract(2,12,\"c:\\tmp\\a.pdf\")"},{"kind":1,"language":"markdown","value":"## Outline / bookmarks"},{"kind":1,"language":"markdown","value":"### sequence of maps"},{"kind":2,"language":"xquery","value":"\r\npdfbox:open($PDF)=>pdfbox:outline()"},{"kind":1,"language":"markdown","value":"XML"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)=>pdfbox:outline()=>pdfbox:outline-xml()"},{"kind":1,"language":"markdown","value":"## Page labels"},{"kind":2,"language":"xquery","value":"\r\npdfbox:open($PDF)=>pdfbox:pageLabels()"},{"kind":1,"language":"markdown","value":"# getText from page index"},{"kind":2,"language":"xquery","value":"let $doc:=pdfbox:open($PDF)\r\nreturn pdfbox:getText($doc,56)"},{"kind":1,"language":"markdown","value":"# Page scraping"},{"kind":1,"language":"markdown","value":"## pdf scrape text analysis"},{"kind":2,"language":"xquery","value":"let $doc:=pdfbox:open($PDF)\r\nreturn pdfscrape:page-report($doc)\r\n"},{"kind":1,"language":"markdown","value":"## Inverted pageno map"},{"kind":2,"language":"xquery","value":"let $doc:=pdfbox:open($PDF)\r\nreturn pdfscrape:page-report($doc)=>pdfscrape:inverted-map()"},{"kind":1,"language":"markdown","value":"# Save images"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)\r\n=> pdfbox:pageBufferedImage(99,1)\r\n=>pdfbox:imageSave(\"c:\\tmp\\page3.png\",\"png\")\r\n"},{"kind":2,"language":"xquery","value":"pdfbox:open($PDF)\r\n=> pdfbox:pageBufferedImage(3,0.25)\r\n=>pdfbox:imageBinary(\"jpg\")"},{"kind":1,"language":"markdown","value":"## report"},{"kind":2,"language":"xquery","value":"declare variable $a:=file:resolve-path(\"../data/1e/\",file:base-dir());\r\n\r\nfor $f in file:list($a,true(),\"*.pdf\") \r\nwhere not(contains($f,\"outputs\"))\r\nlet $doc:=pdfbox:open(file:resolve-path($f,$a))\r\n(: let $outline:=pdfbox:outline($doc) :)\r\nlet $count:=pdfbox:page-count($doc)\r\norder by $count \r\nreturn ``[`{$f}`: `{ $count }`]``"},{"kind":2,"language":"xquery","value":"declare variable $a:=file:resolve-path(\"../data/1e/\",file:base-dir());\r\n\r\nfor $f at $pos in file:list($a,true(),\"*.pdf\") \r\nwhere not(contains($f,\"outputs\"))\r\nreturn pdfbox:open(file:resolve-path($f,$a))\r\n=> pdfbox:pageAsImage(0,0.25)\r\n=> pdfbox:imageSave(``[c:\\tmp\\titles\\p`{$pos}`.gif]``,\"gif\")"}]} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 969fb05..0000000 --- a/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "pdfbox", - "lockfileVersion": 3, - "requires": true, - "packages": {} -} diff --git a/package.json b/package.json new file mode 100644 index 0000000..52ffdb2 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "pdfbox", + "version": "1.0.0", + "description": "A BaseX interface to Apache Pdfbox version 3", + "main": "index.js", + "directories": { + "doc": "docs" + }, + "scripts": { + "test": "basex -t ." + }, + "keywords": [ + "pdf", + "xquery", + "basex", + "java" + ], + "author": "Andy Bunce", + "license": "Apache-2.0" +} diff --git a/samples.pdf/Sentience-in-Cephalopod-Molluscs-and-Decapod-Crustaceans-Final-Report-November-2021.pdf b/samples.pdf/Sentience-in-Cephalopod-Molluscs-and-Decapod-Crustaceans-Final-Report-November-2021.pdf new file mode 100644 index 0000000..e1fad2f Binary files /dev/null and b/samples.pdf/Sentience-in-Cephalopod-Molluscs-and-Decapod-Crustaceans-Final-Report-November-2021.pdf differ diff --git a/samples.pdf/readme.md b/samples.pdf/readme.md index 5974a95..ed973fd 100644 --- a/samples.pdf/readme.md +++ b/samples.pdf/readme.md @@ -1,5 +1,7 @@ # Example PDFs with pageLabels and outlines +## Sources * [BaseX100.pdf](https://files.basex.org/releases/10.0/BaseX100.pdf) * [icelandic-dictionary.pdf](http://css4.pub/2015/icelandic/dictionary.pdf) -* [page-numbers.pdf](https://www.w3.org/WAI/WCAG22/working-examples/pdf-page-numbers/page-numbers.pdf) +* [page-numbers.pdf](https://www.w3.org/WAI/WCAG22/working-examples/pdf-page-numbers/page-numbers). +* [Sentience-in-Cephalopod-Molluscs-and-Decapod-Crustaceans](https://www.lse.ac.uk/News/News-Assets/PDFs/2021/Sentience-in-Cephalopod-Molluscs-and-Decapod-Crustaceans-Final-Report-November-2021.pdfpdf) diff --git a/src/lib/.xqdoca b/src/lib/.xqdoca new file mode 100644 index 0000000..5016091 --- /dev/null +++ b/src/lib/.xqdoca @@ -0,0 +1 @@ +.xqdoca/ \ No newline at end of file diff --git a/src/lib/pdfbox3.xqm b/src/lib/pdfbox3.xqm index 790ffb5..e90e4e2 100644 --- a/src/lib/pdfbox3.xqm +++ b/src/lib/pdfbox3.xqm @@ -244,12 +244,14 @@ as map(*){ )=>map:merge() }; -(:~ page (ZERO based) as image -@param $scale 1=72 dpi :) -declare function pdfbox:pageAsImage($doc as item(), $pageNo as xs:integer,$scale as xs:float) +(:~ java:bufferedImage for $pageNo using $scale times dpi= 72 +@param $pageNo (ZERO based) +@param $scale 1=72 dpi +@return Java java.awt.image.BufferedImage object +:) +declare function pdfbox:pageBufferedImage($doc as item(), $pageNo as xs:integer,$scale as xs:float) as item(){ - PDFRenderer:new($doc) - =>PDFRenderer:renderImage($pageNo,$scale) + PDFRenderer:new($doc)=>PDFRenderer:renderImage($pageNo,$scale) }; (:~ save bufferedimage to $dest @@ -258,3 +260,13 @@ declare function pdfbox:imageSave($bufferedImage as item(),$dest as xs:string,$t as xs:boolean{ Q{java:javax.imageio.ImageIO}write($bufferedImage , $type, File:new($dest)) }; + +(:~ return image +@param $type = "gif","png" etc:) +declare function pdfbox:imageBinary($bufferedImage as item(),$type as xs:string) +as xs:base64Binary{ + let $bytes:=Q{java:java.io.ByteArrayOutputStream}new() + let $_:=Q{java:javax.imageio.ImageIO}write($bufferedImage , $type, $bytes) + return Q{java:java.io.ByteArrayOutputStream}toByteArray($bytes) + =>convert:integers-to-base64() +}; \ No newline at end of file diff --git a/src/lib/pdfscrape.xqm b/src/lib/pdfscrape.xqm index f5fe8c6..dfde25c 100644 --- a/src/lib/pdfscrape.xqm +++ b/src/lib/pdfscrape.xqm @@ -5,26 +5,26 @@ pdfscrape:page-report($doc )=>pdfscrape:inverted-map() module namespace pdfscrape = 'urn:pdfscrape'; import module namespace pdfbox="urn:expkg-zone58:pdfbox3" at "pdfbox3.xqm"; -(: look for possible page number in first/last line of page text +(:~ page number regex @todo last line and roman 1=Number system ( D=decimal, R=Roman) 2=Side L=left,R=right :) -declare variable $pdfscrape:pats:=map{ +declare %private variable $pdfscrape:pats:=map{ "DL": "^([1-9][0-9]*).*", "DR": ".*[^0-9]([1-9][0-9]*)$", "RL": "^([ivxlc]+).*", "RR": ".*[^ivxlc]([ivxlc]+)$" }; -(: page-reports for all pages :) +(:~ page-reports for all pages :) declare function pdfscrape:page-report($doc as item()) as element(page)*{ let $count:=pdfbox:page-count($doc)=>trace("Pages: ") return (1 to $count )!pdfscrape:page-report($doc,.) }; -(: page-report for given page :) +(:~ page-report for given page :) declare function pdfscrape:page-report($doc as item(), $page as xs:integer) as element(page){ let $txt:=pdfbox:getText($doc,$page) @@ -35,7 +35,7 @@ as element(page){ return { $found, $line1 } }; -(: empty or attributes created by matching $style with $line1 :) +(:~ empty or attributes created by matching $style with $line1 :) declare function pdfscrape:line-report($style as xs:string, $line1 as xs:string) as attribute(*)*{ if(matches($line1,$pdfscrape:pats?($style))) diff --git a/src/webapp/pdf/api.xqm b/src/webapp/pdf/api.xqm deleted file mode 100644 index 1519946..0000000 --- a/src/webapp/pdf/api.xqm +++ /dev/null @@ -1,30 +0,0 @@ -(:~ - pdf - :) -module namespace api = 'pdf/api'; -import module namespace functx = "http://www.functx.com"; -(:~ list slugs :) -declare - %rest:path('/pdf/api/sources') - %output:method("json") - %output:json("format=xquery") -function api:apt() as map(*) -{ - let $base:="C:/Users/mrwhe/git/expkg-zone58/pdfbox/data/" - let $d:="1e/" - let $f:=file:list($base || $d,true(),"*.pdf")[not(contains(.,"\outputs\"))] - return map{ - "count": count($f), - "items": array{$f!api:path-info(.)} - } -}; - -declare function api:path-info($file as xs:string) -as map(*) -{ - map{ - "id": $file, - "slug":functx:substring-before-last($file,"\"), - "filename": file:name($file) - } -}; diff --git a/src/webapp/pdf/app.xqm b/src/webapp/pdf/app.xqm deleted file mode 100644 index 444504f..0000000 --- a/src/webapp/pdf/app.xqm +++ /dev/null @@ -1,47 +0,0 @@ -(:~ - pdf - :) -module namespace pdf = 'pdf/common'; - - - -(:~ - : Redirects to the start page. - : @return redirection - :) -declare - %rest:path('/pdf') -function pdf:home() as element() { - web:forward('/pdf/static/index.html') -}; -declare - %rest:path('/pdf/{$file=.+}') -function pdf:spa($file)as element(){ -pdf:home() -}; - -(:~ - : Returns a file. - : @param $file file or unknown path - : @return rest binary data - :) -declare - %rest:path('/pdf/static/{$file=.+}') - %output:method('basex') - %perm:allow('public') -function pdf:file( - $file as xs:string -) as item()+ { - let $path := file:base-dir() || "static/" || $file - return if(file:exists($path)) - then ( - web:response-header( - map { 'media-type': web:content-type($path) }, - map { 'Cache-Control': 'max-age=3600,public', 'Content-Length': file:size($path) } - ), - file:read-binary($path) - )else - () - -}; - diff --git a/src/webapp/pdf/package-lock.json b/src/webapp/pdf/package-lock.json deleted file mode 100644 index d981400..0000000 --- a/src/webapp/pdf/package-lock.json +++ /dev/null @@ -1,164 +0,0 @@ -{ - "name": "pdf", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "@shoelace-style/shoelace": "^2.15.0" - } - }, - "node_modules/@ctrl/tinycolor": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.0.3.tgz", - "integrity": "sha512-e9nEVehVJwkymQpkGhdSNzLT2Lr9UTTby+JePq4Z2SxBbOQjY7pLgSouAaXvfaGQVSAaY0U4eJdwfSDmCbItcw==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.0.tgz", - "integrity": "sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==", - "dependencies": { - "@floating-ui/utils": "^0.2.1" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.3.tgz", - "integrity": "sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==", - "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.1.tgz", - "integrity": "sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==" - }, - "node_modules/@lit-labs/ssr-dom-shim": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz", - "integrity": "sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==" - }, - "node_modules/@lit/react": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@lit/react/-/react-1.0.4.tgz", - "integrity": "sha512-6HBvk3AwF46z17fTkZp5F7/EdCJW9xqqQgYKr3sQGgoEJv0TKV1voWydG4UQQA2RWkoD4SHjy08snSpzyoyd0w==", - "peerDependencies": { - "@types/react": "17 || 18" - } - }, - "node_modules/@lit/reactive-element": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@lit/reactive-element/-/reactive-element-2.0.4.tgz", - "integrity": "sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0" - } - }, - "node_modules/@shoelace-style/animations": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@shoelace-style/animations/-/animations-1.1.0.tgz", - "integrity": "sha512-Be+cahtZyI2dPKRm8EZSx3YJQ+jLvEcn3xzRP7tM4tqBnvd/eW/64Xh0iOf0t2w5P8iJKfdBbpVNE9naCaOf2g==", - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/claviska" - } - }, - "node_modules/@shoelace-style/localize": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@shoelace-style/localize/-/localize-3.1.2.tgz", - "integrity": "sha512-Hf45HeO+vdQblabpyZOTxJ4ZeZsmIUYXXPmoYrrR4OJ5OKxL+bhMz5mK8JXgl7HsoEowfz7+e248UGi861de9Q==" - }, - "node_modules/@shoelace-style/shoelace": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/@shoelace-style/shoelace/-/shoelace-2.15.0.tgz", - "integrity": "sha512-Lcg938Y8U2VsHqIYewzlt+H1rbrXC4GRSUkTJgXyF8/0YAOlI+srd5OSfIw+/LYmwLP2Peyh398Kae/6tg4PDA==", - "dependencies": { - "@ctrl/tinycolor": "^4.0.2", - "@floating-ui/dom": "^1.5.3", - "@lit/react": "^1.0.0", - "@shoelace-style/animations": "^1.1.0", - "@shoelace-style/localize": "^3.1.2", - "composed-offset-position": "^0.0.4", - "lit": "^3.0.0", - "qr-creator": "^1.0.0" - }, - "engines": { - "node": ">=14.17.0" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/claviska" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.12", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "peer": true - }, - "node_modules/@types/react": { - "version": "18.2.74", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.74.tgz", - "integrity": "sha512-9AEqNZZyBx8OdZpxzQlaFEVCSFUM2YXJH46yPOiOpm078k6ZLOCcuAzGum/zK8YBwY+dbahVNbHrbgrAwIRlqw==", - "peer": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" - }, - "node_modules/composed-offset-position": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/composed-offset-position/-/composed-offset-position-0.0.4.tgz", - "integrity": "sha512-vMlvu1RuNegVE0YsCDSV/X4X10j56mq7PCIyOKK74FxkXzGLwhOUmdkJLSdOBOMwWycobGUMgft2lp+YgTe8hw==" - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "peer": true - }, - "node_modules/lit": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lit/-/lit-3.1.2.tgz", - "integrity": "sha512-VZx5iAyMtX7CV4K8iTLdCkMaYZ7ipjJZ0JcSdJ0zIdGxxyurjIn7yuuSxNBD7QmjvcNJwr0JS4cAdAtsy7gZ6w==", - "dependencies": { - "@lit/reactive-element": "^2.0.4", - "lit-element": "^4.0.4", - "lit-html": "^3.1.2" - } - }, - "node_modules/lit-element": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lit-element/-/lit-element-4.0.4.tgz", - "integrity": "sha512-98CvgulX6eCPs6TyAIQoJZBCQPo80rgXR+dVBs61cstJXqtI+USQZAbA4gFHh6L/mxBx9MrgPLHLsUgDUHAcCQ==", - "dependencies": { - "@lit-labs/ssr-dom-shim": "^1.2.0", - "@lit/reactive-element": "^2.0.4", - "lit-html": "^3.1.2" - } - }, - "node_modules/lit-html": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lit-html/-/lit-html-3.1.2.tgz", - "integrity": "sha512-3OBZSUrPnAHoKJ9AMjRL/m01YJxQMf+TMHanNtTHG68ubjnZxK0RFl102DPzsw4mWnHibfZIBJm3LWCZ/LmMvg==", - "dependencies": { - "@types/trusted-types": "^2.0.2" - } - }, - "node_modules/qr-creator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/qr-creator/-/qr-creator-1.0.0.tgz", - "integrity": "sha512-C0cqfbS1P5hfqN4NhsYsUXePlk9BO+a45bAQ3xLYjBL3bOIFzoVEjs79Fado9u9BPBD3buHi3+vY+C8tHh4qMQ==" - } - } -} diff --git a/src/webapp/pdf/package.json b/src/webapp/pdf/package.json deleted file mode 100644 index 743c656..0000000 --- a/src/webapp/pdf/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "dependencies": { - "@shoelace-style/shoelace": "^2.15.0" - } -} diff --git a/src/webapp/pdf/readme.md b/src/webapp/pdf/readme.md deleted file mode 100644 index 46fbfa5..0000000 --- a/src/webapp/pdf/readme.md +++ /dev/null @@ -1,24 +0,0 @@ -Uses -* https://github.com/blikblum/slick-router#readme -* https://dev.to/blikblum/slick-router-a-powerful-router-for-web-components-3fck - -## Sync -``` -cd C:\Users\mrwhe\git\expkg-zone58\pdfbox\src\webapp\pdf - -c:\DeltaCopy\rsync -rlptz --progress --exclude=.git --exclude=.vscode . andy@localhost::basexserv/ -``` -## random html in markdown - - - - - - - - - -
Sample table
Foo
3
\ No newline at end of file diff --git a/src/webapp/pdf/static/animations.css b/src/webapp/pdf/static/animations.css deleted file mode 100644 index fad7e5c..0000000 --- a/src/webapp/pdf/static/animations.css +++ /dev/null @@ -1,53 +0,0 @@ -/* extracted from https://vuejs.org/v2/guide/transitions.html */ - -.fade-enter-active, -.fade-leave-active { - transition: opacity 0.5s; -} - -.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { - opacity: 0; -} - -/* Enter and leave animations can use different */ -/* durations and timing functions. */ -.slide-fade-enter-active { - transition: all 0.3s ease; -} - -.slide-fade-leave-active { - transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1); -} - -.slide-fade-enter, .slide-fade-leave-to { - transform: translateX(1000px); - opacity: 0; -} - -.bounce-enter { - opacity: 0; -} - -.bounce-enter-active { - animation: bounce-in 0.8s; -} - -.bounce-leave-active { - animation: bounce-in 0.8s reverse; -} - -@keyframes bounce-in { - 0% { - transform: scale(0); - } - 80% { - transform: scale(1.1); - } - 100% { - transform: scale(1); - } -} - -router-outlet > * { - display: block; -} diff --git a/src/webapp/pdf/static/components.js b/src/webapp/pdf/static/components.js deleted file mode 100644 index b028713..0000000 --- a/src/webapp/pdf/static/components.js +++ /dev/null @@ -1,290 +0,0 @@ -import { withRouterLinks } from 'https://unpkg.com/slick-router@2.5.0/middlewares/router-links.js' - -customElements.define('application-view', - class ApplicationView extends withRouterLinks(HTMLElement) { - constructor() { - super() - this.addEventListener('change', e => { - if (e.target.matches('#animation-type')) { - const animation = e.target.value - if (animation) { - this.outlet.setAttribute('animation', e.target.value) - } else { - this.outlet.removeAttribute('animation') - } - } - }) - this.addEventListener('load', e => { - const data = e.detail; - notify(JSON.stringify(data.items[0])); - } - ) - // Custom function to emit toast notifications - function notify(message, variant = 'primary', icon = 'info-circle', duration = 3000) { - const alert = Object.assign(document.createElement('sl-alert'), { - variant, - closable: true, - duration: duration, - innerHTML: ` - - ${message} - ` - }); - - document.body.append(alert); - return alert.toast(); - } - // Always escape HTML for text arguments! - function escapeHtml(html) { - const div = document.createElement('div'); - div.textContent = html; - return div.innerHTML; - } - this.addEventListener('click', e => { - if (e.target.matches('#more-toast')) { - const alert = this.querySelector('#toaster') - notify(`This is custom toast `); - } - }) - } - - connectedCallback() { - super.connectedCallback() - this.innerHTML = ` -
-
-

Application

- - - -
- - - - -
- ` - this.outlet = this.querySelector('router-outlet') - } - } -) -customElements.define('home-view', - class HomeView extends withRouterLinks(HTMLElement) { - connectedCallback() { - this.getModel(); - } - getModel() { - return new Promise((res, rej) => { - fetch('/pdf/api/sources') - .then(data => data.json()) - .then((json) => { - this.renderPosts(json); - res(); - }) - .catch((error) => rej(error)); - }) - } - renderPosts(data) { - const count = data.count - const shadowRoot = this.attachShadow({ mode: "open" }); - const div = document.createElement("div", { class: "cards" }); - shadowRoot.appendChild(div); - data.items.forEach(item => { - div.appendChild(Object.assign( - document.createElement('sl-card'), { class: "card", textContent: item.slug }) - ) - }) - } - } -) - -customElements.define('tweet-view', - class TweetView extends withRouterLinks(HTMLElement) { - connectedCallback() { - super.connectedCallback() - this.innerHTML = ` -
-

Tweets

-
- -
12m12 minutes ago
-
Another use case for \`this.context\` I think might be valid: forms. They're too painful right now.
-
-
- -
12m12 minutes ago
-
I just published “What will Datasmoothie bring to the analytics startup landscape?” https://medium.com/@afanasjevas/what-will-datasmoothie-bring-to-the-analytics-startup-landscape-f7dab70d75c3?source=tw-81c4e81fe6f8-1427630532296
-
-
- -
52m52 minutes ago
-
new talks uploaded on our YouTube page - check them out http://bit.ly/1yoXSAO
-
-
- ` - } - } -) -customElements.define('messages-view', - class MessagesView extends HTMLElement { - connectedCallback() { - this.innerHTML = ` -
-

Messages

-

You have no direct messages

- - Available Trees - - - - -
- ` - } - } -) -customElements.define('settings-view', - class SettingsView extends HTMLElement { - connectedCallback() { - this.innerHTML = ` -
- DATA -

Settings

-
- Animation - -
- - - Your settings have been updated
- Settings will take effect on next login. -
- -
- ` - } - } -) -customElements.define('profile-view', - class ProfileView extends HTMLElement { - static get outlet() { - return '.Container' - } - - connectedCallback() { - this.innerHTML = ` -
-
-
- ` - } - } -) - -customElements.define('profile-index-view', - class ProfileIndexView extends HTMLElement { - - connectedCallback() { - - this.innerHTML = ` -
-

${this.$route.params.user} profile

-
- ` - } - } -) -customElements.define('cards-panel', - class CardPanel extends HTMLElement { - constructor(){ - super(); - const template = document.createElement('template'); - template.id = 'pool-calculator-template'; - template.innerHTML = ` - - -
- - - -
- `; - } - connectedCallback() { - this.innerHTML = ` -
-

${this.$route.params.user} profile

-
- ` - } - } -) -customElements.define('fetch-json', - class FetchJson extends HTMLElement { - static observedAttributes = ["src", "size"]; - - connectedCallback() { - this.getModel(); - } - getModel() { - const src = this.getAttribute('src') - + "?" + new URLSearchParams({ foo: 'value', bar: 2, }); - return new Promise((res, rej) => { - fetch(src) - .then(data => data.json()) - .then((json) => { - this.data=data; - this.renderPosts(json); - res(); - }) - .catch((error) => rej(error)); - }) - } - renderPosts(data) { - this.innerHTML = `${this.getAttribute('src')} : ${data.count}`; - - this.dispatchEvent(new CustomEvent("load", { - detail: data, - composed: true, - bubbles: true - })); - } - } -) diff --git a/src/webapp/pdf/static/favicon.png b/src/webapp/pdf/static/favicon.png deleted file mode 100644 index 1c0d0cb..0000000 Binary files a/src/webapp/pdf/static/favicon.png and /dev/null differ diff --git a/src/webapp/pdf/static/index.html b/src/webapp/pdf/static/index.html deleted file mode 100644 index 699f72a..0000000 --- a/src/webapp/pdf/static/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - PDFS453 - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/webapp/pdf/static/index.js b/src/webapp/pdf/static/index.js deleted file mode 100644 index a681c20..0000000 --- a/src/webapp/pdf/static/index.js +++ /dev/null @@ -1,43 +0,0 @@ -import { Router } from 'https://unpkg.com/slick-router@2.5.0/slick-router.js?module' -import { wc } from 'https://unpkg.com/slick-router@2.5.0/middlewares/wc.js' -import { events } from 'https://unpkg.com/slick-router@2.5.0/middlewares/events.js' -import { routerLinks } from 'https://unpkg.com/slick-router@2.5.0/middlewares/router-links.js' -import { AnimatedOutlet } from 'https://unpkg.com/slick-router@2.5.0/components/animated-outlet.js' - -import './components.js' - -customElements.define('router-outlet', AnimatedOutlet) - -// create the router -const router = new Router({ - pushState: true, - - log: true -}) - -// provide your route map -// in this particular case we configure components by its tag name - -router.map(route => { - route('application', { path: '/pdf/', - component: 'application-view' }, () => { - route('home', { path: '', component: 'home-view' }) - route('tweets', { component: 'tweet-view' }) - route('messages', { component: 'messages-view' }) - route('status', { path: ':user/status/:id' }) - route('profile', { path: 'profile/:user', component: 'profile-view' }, () => { - route('profile.index', { path: '', component: 'profile-index-view' }) - route('profile.lists') - route('profile.edit') - }) - route('settings',{path: 'settings',component:'settings-view'}) - }) -}) - -// install middleware that will handle transitions -router.use(wc) -router.use(routerLinks) -router.use(events) - -// start listening to browser's location bar changes -router.listen() diff --git a/src/webapp/pdf/static/styles.css b/src/webapp/pdf/static/styles.css deleted file mode 100644 index 00f1608..0000000 --- a/src/webapp/pdf/static/styles.css +++ /dev/null @@ -1,97 +0,0 @@ -@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700'); - -body, -html { - margin: 0; - padding: 0; - font-family: 'Open Sans', sans-serif; -} -sl-card { - display: flex; - width: 100px; -} - -.App { - width: 800px; - margin: 0 auto 20px auto; -} - -.App-header { - border-bottom: 1px solid #eee; -} - -.App-header .active { - font-weight: bolder; -} - -.App-footer { - position: fixed; - left: 0; - bottom: 0; - width: 100%; - padding-bottom: 20px; - text-align: center; - background-color: bisque; -} - -.App h1 { - display: inline-block; -} - -.Nav { - display: inline-block; -} - -.Nav-item { - list-style: none; - display: inline-block; -} - -.Nav-item a { - padding: 10px; -} - -.Tweet { - border: 1px solid #eee; - border-radius: 3px; - padding: 10px; - border-bottom: none; -} - -.Tweet:last-child { - border-bottom: 1px solid #eee; -} - -.Tweet-author { - font-weight: bold; - display: inline-block; -} - -.Tweet-time { - color: #888; - display: inline-block; - margin-left: 20px; - font-size: 12px; -} - -router-outlet > * { - display: block; -} - -.card-header { - max-width: 300px; -} - -.card-header [slot='header'] { - display: flex; - align-items: center; - justify-content: space-between; -} - -.card-header h3 { - margin: 0; -} - -.card-header sl-icon-button { - font-size: var(--sl-font-size-medium); -} \ No newline at end of file diff --git a/src/webapp/pdf/static/summary-display.js b/src/webapp/pdf/static/summary-display.js deleted file mode 100644 index 474c22e..0000000 --- a/src/webapp/pdf/static/summary-display.js +++ /dev/null @@ -1,47 +0,0 @@ -customElements.define('summary-display', - class extends HTMLElement { - constructor() { - super(); - - const template = document.getElementById('summary-display-template'); - const templateContent = template.content; - - const shadowRoot = this.attachShadow({mode: 'open'}); - shadowRoot.appendChild(templateContent.cloneNode(true)); - - const items = Array.from(this.querySelectorAll('li')); - const descriptions = Array.from(this.querySelectorAll('p')); - - items.forEach(item => { - handleClick(item); - }); - - function handleClick(item) { - item.addEventListener('click', function() { - items.forEach(item => { - item.style.backgroundColor = 'white'; - }); - - descriptions.forEach(description => { - updateDisplay(description, item); - }); - }); - } - - function updateDisplay(description, item) { - description.removeAttribute('slot'); - - if(description.getAttribute('data-name') === item.textContent) { - description.setAttribute('slot', 'choice'); - item.style.backgroundColor = '#bad0e4'; - } - } - - const slots = this.shadowRoot.querySelectorAll('slot'); - slots[1].addEventListener('slotchange', function(e) { - const nodes = slots[1].assignedNodes(); - console.log(`Element in Slot "${slots[1].name}" changed to "${nodes[0].outerHTML}".`); - }); - } - } -); diff --git a/src/webapp/pdf/static/user.html b/src/webapp/pdf/static/user.html deleted file mode 100644 index e99206a..0000000 --- a/src/webapp/pdf/static/user.html +++ /dev/null @@ -1,32 +0,0 @@ - - - \ No newline at end of file