aboutsummaryrefslogtreecommitdiff
path: root/pptxzip.f90
diff options
context:
space:
mode:
Diffstat (limited to 'pptxzip.f90')
-rw-r--r--pptxzip.f90204
1 files changed, 204 insertions, 0 deletions
diff --git a/pptxzip.f90 b/pptxzip.f90
new file mode 100644
index 0000000..d526125
--- /dev/null
+++ b/pptxzip.f90
@@ -0,0 +1,204 @@
+! Copyright (c) 2022 Approximatrix, LLC <support@approximatrix.com>
+!
+! Permission is hereby granted, free of charge, to any person obtaining a copy
+! of this software and associated documentation files (the "Software"), to deal
+! in the Software without restriction, including without limitation the rights
+! to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+! copies of the Software, and to permit persons to whom the Software is
+! furnished to do so, subject to the following conditions:
+!
+! The above copyright notice and this permission notice shall be included in
+! all copies or substantial portions of the Software.
+!
+! The Software shall be used for Good, not Evil.
+!
+! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+! IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+! FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+! AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+! LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+! OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+! SOFTWARE.
+
+module fpoint_pptxzip
+use fpoint_pptxml
+implicit none
+
+ private
+ public::pptxtracted
+
+ type :: pptxtracted
+
+ character(len=2048)::directory
+ character(len=2048), dimension(:), pointer::slide_paths
+ character(len=2048), dimension(:), pointer::note_paths
+
+ type(slide), dimension(:), pointer::slides
+
+ contains
+
+ procedure :: open => pptx_open
+ procedure :: close => pptx_close
+ procedure :: parse => pptx_parse
+ procedure :: to_text => pptx_to_text
+ procedure :: slide_has_notes
+ procedure :: slide_count
+
+ end type pptxtracted
+
+contains
+
+ function slide_has_notes(self, i)
+ implicit none
+
+ class(pptxtracted), intent(in)::self
+ integer, intent(in)::i
+ logical::slide_has_notes
+
+ if(i > size(self%note_paths) .or. i < 1) then
+ slide_has_notes = .false.
+ else
+ slide_has_notes = (len_trim(self%note_paths(i)) > 0)
+ end if
+
+ end function slide_has_notes
+
+ function slide_count(self)
+ implicit none
+
+ class(pptxtracted), intent(in)::self
+ integer::slide_count
+
+ if(associated(self%slide_paths)) then
+ slide_count = size(self%slide_paths)
+ else
+ slide_count = 0
+ end if
+
+ end function slide_count
+
+ function pptx_open(self, filename) result(res)
+ use fpoint_fsutil
+ use m_unzip, only: unzip
+ implicit none
+
+ logical::res
+ class(pptxtracted), intent(out)::self
+ character(len=*), intent(in)::filename
+ integer::i, slidecount
+ character(len=2048)::slidedir, slidecheck, notesdir
+ character(len=4)::numtext
+ logical::existence
+
+ call get_temporary_directory(self%directory)
+ i = index(filename, pathsep, back=.true.) + 1
+ call append_to_path(self%directory, filename(i:len_trim(filename))//".extracted")
+ call make_directory(trim(self%directory))
+
+ ! Extract the file into said directory
+ res = unzip(filename, trim(self%directory))
+
+ ! Count slides
+ slidedir = self%directory
+ call append_to_path(slidedir, 'ppt')
+ call append_to_path(slidedir, 'slides')
+ do i = 1, 512
+ slidecheck = slidedir
+ write(numtext, '(I4)') i
+ call append_to_path(slidecheck, "slide"//trim(adjustl(numtext))//".xml")
+ inquire(file=slidecheck, exist=existence)
+ if(.not. existence) then
+ exit
+ end if
+ end do
+ slidecount = i - 1
+
+ allocate(self%slide_paths(slidecount))
+ self%slide_paths = slidedir
+ do i = 1, slidecount
+ write(numtext, '(I4)') i
+ call append_to_path(self%slide_paths(i), "slide"//trim(adjustl(numtext))//".xml")
+ end do
+
+ ! Now check for notes
+ notesdir = self%directory
+ call append_to_path(notesdir, 'ppt')
+ call append_to_path(notesdir, 'notesSlides')
+ allocate(self%note_paths(slidecount))
+ self%note_paths = notesdir
+ do i = 1, slidecount
+ write(numtext, '(I4)') i
+ call append_to_path(self%note_paths(i), "notesSlide"//trim(adjustl(numtext))//".xml")
+ inquire(file=self%note_paths(i), exist=existence)
+ if(.not. existence) then
+ self%note_paths(i) = " "
+ end if
+ end do
+
+ ! These should only be explicitly parsed
+ self%slides => null()
+
+ end function pptx_open
+
+ subroutine pptx_close(self)
+ implicit none
+
+ class(pptxtracted), intent(inout)::self
+
+ ! Delete directory tree at self%directory
+
+ deallocate(self%slide_paths)
+ self%slide_paths => null()
+
+ deallocate(self%note_paths)
+ self%note_paths => null()
+
+ self%directory = " "
+
+ end subroutine pptx_close
+
+ subroutine pptx_parse(self)
+ use fpoint_pptxml
+ implicit none
+
+ class(pptxtracted), intent(inout)::self
+ integer::i
+ allocate(self%slides(self%slide_count()))
+
+ do i = 1, self%slide_count()
+ call self%slides(i)%load(self%slide_paths(i))
+ end do
+
+ end subroutine pptx_parse
+
+ function pptx_to_text(self) result(t)
+ use fpoint_pptxml
+ implicit none
+
+ class(pptxtracted), intent(in)::self
+ integer::text_length
+ character(len=:), pointer::t, tmp
+ integer::i
+
+ t => null()
+
+ if(self%slide_count() > 0 .and. associated(self%slides)) then
+ text_length = 0
+ do i = 1, self%slide_count()
+ text_length = text_length + self%slides(i)%text_length()
+ end do
+
+ allocate(character(len=text_length) :: t)
+
+ text_length = 1
+ do i = 1, self%slide_count()
+ tmp => self%slides(i)%to_text()
+ t(text_length:len(t)) = trim(tmp)
+ text_length = text_length + len_trim(tmp)
+ end do
+
+ end if
+
+ end function pptx_to_text
+
+end module fpoint_pptxzip