aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2022-03-01 09:52:02 -0500
committerJeffrey Armstrong <jeff@approximatrix.com>2022-03-01 09:52:02 -0500
commitdbdfb68893a5b9677a9286beff8de3c1b02fff5d (patch)
tree39c6efddabf0b62cc89c1b3b79107b37d6ce2a71
parent0a211cd23fcca0b2f7fa175661b7237d3b3b9dce (diff)
downloadfpoint-dbdfb68893a5b9677a9286beff8de3c1b02fff5d.tar.gz
fpoint-dbdfb68893a5b9677a9286beff8de3c1b02fff5d.zip
Slide notes are now extracted, and they can subsequently be output instead. Errors out if no notes are present.
-rw-r--r--driver.f9018
-rw-r--r--fpoint.prj2
-rw-r--r--pptxml.f9054
-rw-r--r--pptxzip.f9092
4 files changed, 143 insertions, 23 deletions
diff --git a/driver.f90 b/driver.f90
index bcd8a25..2521407 100644
--- a/driver.f90
+++ b/driver.f90
@@ -27,7 +27,7 @@ implicit none
type(pptxtracted)::presentation
logical::verbose
logical::notes
- integer::i, j
+ integer::i, j, retcode
character(len=:), pointer::filename, arg
if(command_argument_count() < 1) then
@@ -35,6 +35,7 @@ implicit none
call exit(0)
end if
+ retcode = 0
verbose = .false.
notes = .false.
filename => null()
@@ -73,17 +74,22 @@ implicit none
call maybe_print(verbose, "File opened at "//trim(presentation%directory))
call presentation%parse()
-
- write(*, '(A)') presentation%to_text()
-
+
+ if((.not. notes) .or. presentation%has_notes()) then
+ write(*, '(A)') presentation%to_text(notes_only=notes)
+ else
+ call maybe_print(verbose, "No slide notes found in "//filename)
+ retcode = 1
+ end if
+
call presentation%close()
else
call maybe_print(verbose, "Failed on "//filename)
- call exit(1)
+ retcode = 1
end if
- call exit(0)
+ call exit(retcode)
contains
diff --git a/fpoint.prj b/fpoint.prj
index 5d66372..038a8ed 100644
--- a/fpoint.prj
+++ b/fpoint.prj
@@ -61,7 +61,7 @@
"Launch Using MPI":"false",
"Keep Console":"true",
"External Console":"true",
- "Command Line Arguments":"",
+ "Command Line Arguments":"-n \"Welcome to PowerPoint.pptx\"",
"Build Before Launch":"true"
},
"Build Options":{
diff --git a/pptxml.f90 b/pptxml.f90
index c785bb8..513703e 100644
--- a/pptxml.f90
+++ b/pptxml.f90
@@ -313,12 +313,14 @@ contains
end subroutine parse_slide_sp
- subroutine slide_load_filename(self, filename)
+ subroutine slide_load_filename(self, filename, title)
use FoX_dom
implicit none
class(slide), intent(out)::self
character(len=*), intent(in)::filename
+ character(len=*), intent(in), optional::title
+
character(len=:), pointer::filename_no_backslashes
! For parsing the title out
@@ -369,11 +371,16 @@ contains
return
end if
- self%title => find_slide_title(self%slide_dom)
- if(.not. associated(self%title) .and. self%number > 0) then
- allocate(character(len=16)::self%title)
- write(self%title, '(I8)') self%number
- self%title = "Slide "//trim(adjustl(self%title))
+ if(present(title)) then
+ allocate(character(len=len_trim(title)) :: self%title)
+ self%title = title
+ else
+ self%title => find_slide_title(self%slide_dom)
+ if(.not. associated(self%title) .and. self%number > 0) then
+ allocate(character(len=16)::self%title)
+ write(self%title, '(I8)') self%number
+ self%title = "Slide "//trim(adjustl(self%title))
+ end if
end if
call parse_slide_sp(self)
@@ -520,10 +527,39 @@ contains
class(text_element), intent(inout)::self
type(Node), pointer::n
- type(NodeList), pointer::rows
+ type(NodeList), pointer::rows, paras
+ character(len=:), pointer::one_para
+ integer::text_length, i
+
+ text_length = 0
+ paras => getElementsByTagNameNS(n, drawing_schema, "p")
+ do i = 1, getLength(paras)
+ rows => getElementsByTagNameNS(item(paras, i-1), drawing_schema, "r")
+ one_para => concatenated_text_in_rows(rows)
+ if(associated(one_para)) then
+ text_length = text_length + len_trim(one_para)
+ if(i /= getLength(paras)) then
+ text_length = text_length + len(new_line(' '))
+ end if
+ end if
+ end do
- rows => getElementsByTagNameNS(n, drawing_schema, "r")
- self%text => concatenated_text_in_rows(rows)
+ allocate(character(len=text_length) :: self%text)
+
+ text_length = 1
+ paras => getElementsByTagNameNS(n, drawing_schema, "p")
+ do i = 1, getLength(paras)
+ rows => getElementsByTagNameNS(item(paras, i-1), drawing_schema, "r")
+ one_para => concatenated_text_in_rows(rows)
+ if(associated(one_para)) then
+ self%text(text_length:len(self%text)) = one_para
+ text_length = text_length + len_trim(one_para)
+ if(i /= getLength(paras)) then
+ self%text(text_length:len(self%text)) = new_line(' ')
+ text_length = text_length + len(new_line(' '))
+ end if
+ end if
+ end do
end subroutine text_element_from_node
diff --git a/pptxzip.f90 b/pptxzip.f90
index d526125..1a11b1e 100644
--- a/pptxzip.f90
+++ b/pptxzip.f90
@@ -34,6 +34,9 @@ implicit none
character(len=2048), dimension(:), pointer::note_paths
type(slide), dimension(:), pointer::slides
+
+ type(slide), dimension(:), pointer::notes
+ integer, dimension(:), pointer::slide_note_indices
contains
@@ -43,11 +46,27 @@ implicit none
procedure :: to_text => pptx_to_text
procedure :: slide_has_notes
procedure :: slide_count
+ procedure :: get_notes => slide_get_notes
+ procedure :: has_notes => pptx_has_notes
end type pptxtracted
contains
+ function pptx_has_notes(self)
+ implicit none
+
+ class(pptxtracted), intent(in)::self
+ logical::pptx_has_notes
+
+ if(.not. associated(self%slide_note_indices)) then
+ pptx_has_notes = .false.
+ else
+ pptx_has_notes = (count(self%slide_note_indices > 0) > 0)
+ end if
+
+ end function pptx_has_notes
+
function slide_has_notes(self, i)
implicit none
@@ -63,6 +82,28 @@ contains
end function slide_has_notes
+ function slide_get_notes(self, i, success)
+ implicit none
+
+ class(pptxtracted), intent(in)::self
+ integer, intent(in)::i
+ logical, intent(out), optional::success
+ type(slide)::slide_get_notes
+
+ integer::j
+
+ if(self%slide_has_notes(i)) then
+ j = self%slide_note_indices(i)
+ slide_get_notes = self%notes(j)
+ if(present(success)) then
+ success = .true.
+ end if
+ else if(present(success)) then
+ success = .false.
+ end if
+
+ end function slide_get_notes
+
function slide_count(self)
implicit none
@@ -85,7 +126,7 @@ contains
logical::res
class(pptxtracted), intent(out)::self
character(len=*), intent(in)::filename
- integer::i, slidecount
+ integer::i, slidecount, j
character(len=2048)::slidedir, slidecheck, notesdir
character(len=4)::numtext
logical::existence
@@ -121,6 +162,10 @@ contains
end do
! Now check for notes
+ allocate(self%slide_note_indices(slidecount))
+ self%slide_note_indices = -1
+ j = 1
+
notesdir = self%directory
call append_to_path(notesdir, 'ppt')
call append_to_path(notesdir, 'notesSlides')
@@ -132,11 +177,15 @@ contains
inquire(file=self%note_paths(i), exist=existence)
if(.not. existence) then
self%note_paths(i) = " "
+ else
+ self%slide_note_indices(i) = j
+ j = j + 1
end if
end do
! These should only be explicitly parsed
self%slides => null()
+ self%notes => null()
end function pptx_open
@@ -162,39 +211,68 @@ contains
implicit none
class(pptxtracted), intent(inout)::self
- integer::i
+ integer::i, j
allocate(self%slides(self%slide_count()))
+ allocate(self%notes(count(self%slide_note_indices > 0)))
do i = 1, self%slide_count()
call self%slides(i)%load(self%slide_paths(i))
+ if(self%slide_has_notes(i)) then
+ j = self%slide_note_indices(i)
+ call self%notes(j)%load(self%note_paths(i), title=self%slides(i)%title)
+ end if
end do
end subroutine pptx_parse
- function pptx_to_text(self) result(t)
+ function pptx_to_text(self, notes_only) result(t)
use fpoint_pptxml
implicit none
class(pptxtracted), intent(in)::self
+ logical, intent(in), optional::notes_only
integer::text_length
character(len=:), pointer::t, tmp
integer::i
+ type(slide)::one_note
+
+ logical::local_notes
t => null()
+ local_notes = .false.
+ if(present(notes_only)) then
+ local_notes = notes_only
+ end if
+
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()
+ if(local_notes .and. self%slide_has_notes(i)) then
+ one_note = self%get_notes(i)
+ text_length = text_length + one_note%text_length()
+ else if(.not. local_notes) then
+ text_length = text_length + self%slides(i)%text_length()
+ end if
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)
+ tmp => null()
+ if(local_notes .and. self%slide_has_notes(i)) then
+ one_note = self%get_notes(i)
+ tmp => one_note%to_text()
+ else if(.not. local_notes) then
+ tmp => self%slides(i)%to_text()
+ end if
+
+ if(associated(tmp)) then
+ t(text_length:len(t)) = trim(tmp)
+ text_length = text_length + len_trim(tmp)
+ deallocate(tmp)
+ end if
end do
end if