program staticgen ! Spheniscus Static Generator ! Version : 6, 12-09-2013 ! Benoît Leveugle ! to compile : gfortran -ffree-line-length-400 implicit none integer :: nbfiles,error,n,g,m,last1,last2,report,compt,gg character(len=50), dimension(:), allocatable :: Arbo, Names integer, dimension(:,:), allocatable :: Levels integer, dimension(:), allocatable :: active character(len=50), dimension(1:3) :: pos integer, dimension(:,:), allocatable :: levelandparity character(len=200), dimension(:), allocatable :: fArbo,fRevArbo,fFileArbo integer(4) :: today(3) character(len=4) :: year character(len=2) :: month, day character(len=200) :: sbuf logical, dimension(:), allocatable :: fHaveSons character(len=400) :: buffcharlen character, dimension(1:400) :: buffchar ! Get the date, for sitemap xml call idate(today) ! today(1)=day, (2)=month, (3)=year write(year,'(I4.4)') today(3) write(month,'(I2.2)') today(2) write(day,'(I2.2)') today(1) ! trunk contains the website hierarchy, pre-read to define number of files, and then read. open(10,file='Trunk') !############## Pre-read nbfiles = 0 do n=1,300 read(10,*,iostat=error) if(error /=0) exit nbfiles=nbfiles+1 end do nbfiles=nbfiles print *,'nbfiles',nbfiles close(10) !############## Reading Arbo allocate(Arbo(1:nbfiles),fArbo(1:nbfiles),fRevArbo(1:nbfiles),fFileArbo(1:nbfiles),& &Names(1:nbfiles),Levels(1:3,1:nbfiles),active(1:nbfiles), & & levelandparity(1:4,1:nbfiles), fHaveSons(1:nbfiles)) open(10,file='Trunk') do n=1,nbfiles read(10,*) Levels(1:3,n),Arbo(n),Names(n) end do close(10) ! At this stage, Levels contain the level of each file. If the file is at level 1, then its second and third value are 0, same for level 2, the third value is 0. ! Arbo contains the name with file system compliance (no espaces, etc). Names contains the real name displayed on the web page. !############## Organise Arbo ! Level and parity : 1:3 the hierarchy (father and sons), 4 the current level ! Aim : define for each file it's father(s) in the hierarchy, and set it's current level (1, 2 or 3) ! Special case for index.html because it has to be at root /, not in a folder named /index/ ! last1 keeps in memory the last level 1 file detected, so all next no level 1 files will have this father for level 1. ! last2 keeps in memory the last level 2 file, same. ! fArbo contains the directory where the file is. ! fFileArbo contains the direct link to the file ! fRevArbo contains the way to go root, in order to be relative to other files. ! fHaveSons : true if the file have sons (to generate submenus), false if not ! Organise parity last1 = 0 last2 = 0 do g=1,nbfiles if(g==1) then ! Special case for index.html levelandparity(4,g) = 1 levelandparity(1,g) = 1 levelandparity(2,g) = 0 levelandparity(3,g) = 0 fArbo(g) = './' fFileArbo(g) = trim(adjustl(Arbo(levelandparity(1,g))))//'.html' fRevArbo(g) = './' last1 = g else if( Levels(2,g) == 0 ) then ! Level 1 levelandparity(4,g) = 1 levelandparity(1,g) = g levelandparity(2,g) = 0 levelandparity(3,g) = 0 fArbo(g) = trim(adjustl(Arbo(levelandparity(1,g)))) fFileArbo(g) = trim(adjustl(Arbo(levelandparity(1,g))))//'/'//trim(adjustl(Arbo(levelandparity(1,g))))//'.html' fRevArbo(g) = '../' last1 = g elseif( Levels(3,g)==0 ) then ! Level 2 levelandparity(4,g) = 2 levelandparity(1,g) = last1 levelandparity(2,g) = g levelandparity(3,g) = 0 fArbo(g) = trim(adjustl(Arbo(levelandparity(1,g))))//'/'//trim(adjustl(Arbo(levelandparity(2,g)))) fFileArbo(g) = trim(adjustl(Arbo(levelandparity(1,g))))//'/'//trim(adjustl(Arbo(levelandparity(2,g))))//'/'//trim(adjustl(Arbo(levelandparity(2,g))))//'.html' fRevArbo(g) = '../../' last2 = g else ! Level 3 levelandparity(4,g) = 3 levelandparity(1,g) = last1 levelandparity(2,g) = last2 levelandparity(3,g) = g fArbo(g) = trim(adjustl(Arbo(levelandparity(1,g))))//'/'//trim(adjustl(Arbo(levelandparity(2,g))))//'/'//trim(adjustl(Arbo(levelandparity(3,g)))) fFileArbo(g) = trim(adjustl(Arbo(levelandparity(1,g))))//'/'//trim(adjustl(Arbo(levelandparity(2,g))))//'/'//trim(adjustl(Arbo(levelandparity(3,g))))//'/'//trim(adjustl(Arbo(levelandparity(3,g))))//'.html' fRevArbo(g) = '../../../' end if end if print *,g,levelandparity(:,g),trim(adjustl(Arbo(g))),' ',trim(adjustl(Names(g))) print *,trim(adjustl(fArbo(g))),' ',trim(adjustl(fFileArbo(g))),' ',trim(adjustl(fRevArbo(g))) end do ! Detect if files have sons do g=1,nbfiles fHaveSons(g) = .false. ! Detect Level 1 sons presence if(levelandparity(4,g) == 1) then do n=1,nbfiles if(levelandparity(2,n) /= 0 .AND. levelandparity(1,n) == levelandparity(1,g)) then fHaveSons(g) = .true. exit end if end do end if ! Detect Level 2 sons presence if(levelandparity(4,g) == 2) then do n=1,nbfiles if(levelandparity(3,n) /= 0 .AND. levelandparity(2,n) == levelandparity(2,g)) then fHaveSons(g) = .true. exit end if end do end if ! Of course, Level 3 have no sons print *,g,"has sons ?",fHaveSons(g) end do do g=1,nbfiles ! -> Loop on files ! Destroy previous files open(11,file=trim(adjustl(fFileArbo(g)))) write(11,*) close(11) open(11,file=trim(adjustl(fFileArbo(g)))) write(11,*) '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' write(11,*) '<HTML>' write(11,*) '<HEAD>' write(11,*) ' <link rel="shortcut icon" href="'//trim(adjustl(fRevArbo(g)))//'pict/166-66.ico">' write(11,*) ' <link href="http://fonts.googleapis.com/css?family=Ubuntu+Mono" rel="stylesheet" type="text/css">' write(11,*) ' <link href="'//trim(adjustl(fRevArbo(g)))//'Style.css" rel="stylesheet" type="text/css">' write(11,*) ' <title> '//trim(adjustl(Names(g)))//' </title>' write(11,*) ' <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />' write(11,*) ' ' write(11,*) ' <!-- GOOGLE ANALYTICS -->' write(11,*) ' ' write(11,*) ' <script type="text/javascript">' write(11,*) ' ' write(11,*) ' var _gaq = _gaq || [];' write(11,*) " _gaq.push(['_setAccount', 'UA-40943443-1']);" write(11,*) " _gaq.push(['_trackPageview']);" write(11,*) ' ' write(11,*) ' (function() {' write(11,*) " var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;" write(11,*) " ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';" write(11,*) " var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);" write(11,*) ' })();' write(11,*) ' ' write(11,*) ' </script>' write(11,*) '</HEAD>' write(11,*) '<BODY>' write(11,*) write(11,*) '<div id="Bandana"></div>' write(11,*) write(11,*) '<!--' write(11,*) '+---------------------+' write(11,*) '| MENU |' write(11,*) '+---------------------+' write(11,*) '-->' write(11,*) ! Level 1 menu, for all files if(levelandparity(4,g) == 1 .AND. (fHaveSons(g) .EQV. .false.)) then ! no decoration because no Level 2 and 3 menus write(11,*) '<div id="MenuBar0-ns">' write(11,*) ' <ul>' else write(11,*) '<div id="MenuBar0">' write(11,*) ' <ul>' end if do n=1,nbfiles ! Loop on files, and find all level 1 files. Also detect the current file to set it active (Selected) if(levelandparity(4,n) == 1) then if(n==levelandparity(1,g)) then write(11,*) ' <li>' write(11,*) ' <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'" class="Selected"> '//trim(adjustl(Names(n)))//' </a>' write(11,*) ' </li>' else write(11,*) ' <li>' write(11,*) ' <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'"> '//trim(adjustl(Names(n)))//' </a>' write(11,*) ' </li>' end if end if end do write(11,*) ' </ul>' write(11,*) '</div>' ! Each page contain a Level 2 menu, except thoses who do not have sons if(((fHaveSons(g) .EQV. .true.) .AND. levelandparity(4,g) == 1) .OR. levelandparity(4,g) > 1) then write(11,*) '<div id="MenuBar1">' write(11,*) ' <ul>' do n=1,nbfiles ! Loop on files, and find all level 2 files. Also detect the current file to set it active (Selected) if(levelandparity(4,n) == 2) then if(levelandparity(1,n) == levelandparity(1,g)) then if(n==levelandparity(2,g)) then write(11,*) ' <li>' if((fHaveSons(n) .EQV. .true.)) then ! Set selected and add decoration if have sons. write(11,*) ' <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'" class="Selected"> '//trim(adjustl(Names(n)))//' </a>' else ! Set selected only if no sons. write(11,*) ' <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'" class="Selected-ns"> '//trim(adjustl(Names(n)))//' </a>' end if write(11,*) ' </li>' else write(11,*) ' <li>' write(11,*) ' <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'"> '//trim(adjustl(Names(n)))//' </a>' write(11,*) ' </li>' end if end if end if end do write(11,*) ' </ul>' write(11,*) '</div>' end if ! Each Level 2 and 3 pages contain a Level 3 menu, except Level 2 who do not have sons if( ((fHaveSons(g) .EQV. .true.) .AND. levelandparity(4,g) == 2) .OR. levelandparity(4,g) == 3) then write(11,*) '<div id="MenuBar2">' write(11,*) ' <ul>' do n=1,nbfiles ! Loop on files, and find all level 3 files. Also detect the current file to set it active (Selected) if(levelandparity(4,n) == 3) then if(levelandparity(2,n) == levelandparity(2,g)) then if(n==levelandparity(3,g)) then write(11,*) ' <li>' write(11,*) ' <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'" class="Selected"> '//trim(adjustl(Names(n)))//' </a>' write(11,*) ' </li>' else write(11,*) ' <li>' write(11,*) ' <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'"> '//trim(adjustl(Names(n)))//' </a>' write(11,*) ' </li>' end if end if end if end do write(11,*) ' </ul>' write(11,*) '</div>' end if write(11,*) ' <!--' write(11,*) ' +---------------------+' write(11,*) ' | BODY |' write(11,*) ' +---------------------+' write(11,*) ' -->' write(11,*) '' write(11,*) ' <div id="BackDegrad">' write(11,*) ' <table border="0" width="100%" cellpadding="0" cellspacing="0" >' write(11,*) ' <tr>' write(11,*) ' <td style="width: 5%;" > </td>' write(11,*) ' <td>' write(11,*) ' <div id="Content">' write(11,*) ' <div id="UnderMenuBar1"></div>' write(11,*) ' <div id="UnderMenuBar2"></div>' write(11,*) ' <div id="UnderMenuBar3"></div>' write(11,*) ' <!--' write(11,*) ' +---------------------+' write(11,*) ' | Fil d Ariane |' write(11,*) ' +---------------------+' write(11,*) ' -->' write(11,*) '' write(11,*) ' <div id="Minos">' if(levelandparity(4,g) == 1) write(11,*) ' Current location : /'//& &'<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(levelandparity(1,g))))//'>'//trim(adjustl(Names(levelandparity(1,g))))//'</a>' if(levelandparity(4,g) == 2) write(11,*) ' Current location : /'//& &'<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(levelandparity(1,g))))//'>'//trim(adjustl(Names(levelandparity(1,g))))//'</a>/'//& &'<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(levelandparity(2,g))))//'>'//trim(adjustl(Names(levelandparity(2,g))))//'</a>' if(levelandparity(4,g) == 3) write(11,*) ' Current location : /'//& &'<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(levelandparity(1,g))))//'>'//trim(adjustl(Names(levelandparity(1,g))))//'</a>/'//& &'<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(levelandparity(2,g))))//'>'//trim(adjustl(Names(levelandparity(2,g))))//'</a>/'//& &'<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(levelandparity(3,g))))//'>'//trim(adjustl(Names(levelandparity(3,g))))//'</a>' write(11,*) ' </div>' write(11,*) ' <div id="PixelLine"></div>' write(11,*) ' <!--' write(11,*) ' +---------------------+' write(11,*) ' | Content |' write(11,*) ' +---------------------+' write(11,*) ' -->' write(11,*) '' write(11,*) ' <table border="0" width="100%" cellpadding="0" cellspacing="0" >' write(11,*) ' <td style="width: 2%;" > </td>' write(11,*) ' <td>' write(11,*) '' write(11,*) '' write(11,*) '' close(11) ! Insert Title and first comment call system('cat '//trim(adjustl(fArbo(g)))//'/titlebody'//' >> '//trim(adjustl(fFileArbo(g)))) ! Build page structure menu ! Check if page structure menu needed open(12,file=trim(adjustl(fArbo(g)))//'/body') Report = 0 Compt = 0 do read(12,'(A)',IOSTAT=Report) buffcharlen if(Report < 0) exit !End of file reached if(index(buffcharlen,'"Section"') > 0 ) Compt = Compt + 1 if(index(buffcharlen,'"SubSection"') > 0 ) Compt = Compt + 1 end do close(12) if(Compt > 0) then open(11,file=trim(adjustl(fFileArbo(g))),POSITION='APPEND') write(11,*) '<br>' write(11,*) '<br>' write(11,*) '<u>Page structure :</u><br>' write(11,*) '<br>' write(11,*) '<table border="0" width="100%" cellpadding="0" cellspacing="0">' write(11,*) '<tr>' write(11,*) '<td style="width: 5%;"></td>' write(11,*) '<td style="width: 45%;" valign="top">' write(11,*) '<div id="PageStructure">' ! print *,"opening",trim(adjustl(fArbo(g)))//'/body' open(12,file=trim(adjustl(fArbo(g)))//'/body') Report = 0 do read(12,'(A)',IOSTAT=Report) buffcharlen if(Report < 0) exit !End of file reached if(index(buffcharlen,'"Section"') > 0 ) then ! print *,"find section",buffcharlen read(buffcharlen,'(400A)') buffchar write(buffcharlen,*) buffchar(SCAN(buffcharlen,'>',.false.)+1:SCAN(buffcharlen,'<',.true.)-1) write(11,*) '<a href="#'//trim(adjustl(buffcharlen))//'"><b>✦ '//trim(adjustl(buffcharlen))//'</b></a><br>' endif if(index(buffcharlen,'"SubSection"') > 0 ) then ! print *,"find subsection",buffcharlen read(buffcharlen,'(400A)') buffchar write(buffcharlen,*) buffchar(SCAN(buffcharlen,'>',.false.)+1:SCAN(buffcharlen,'<',.true.)-1) write(11,*) '<a href="#'//trim(adjustl(buffcharlen))//'"> ↘ '//trim(adjustl(buffcharlen))//'</a><br>' endif end do write(11,*) '</div>' write(11,*) '</td>' write(11,*) '<td style="width: 45%;" valign="top">' write(11,*) '</td>' write(11,*) '<td style="width: 5%;"></td>' write(11,*) '</tr></table>' write(11,*) '<br>' close(11) close(12) end if call system('cat '//trim(adjustl(fArbo(g)))//'/body'//' >> '//trim(adjustl(fFileArbo(g)))) ! detect if only intermed page ! protect segfault if(g > 1 .AND. g < nbfiles) then if(Levels(levelandparity(4,g),g-1) /= Levels(levelandparity(4,g),g) .AND. Levels(levelandparity(4,g),g+1) == Levels(levelandparity(4,g),g)) then open(11,file=trim(adjustl(fFileArbo(g))),POSITION='APPEND') ! write(11,*) '<br>' ! write(11,*) '<br>' ! write(11,*) '<div id="Title">'//Names(g)//'</div><br>' write(11,*) '<br>' write(11,*) '<br>' write(11,*) '<div style="text-align: center; font-size: 2.2em; color:#171a1b;">'//trim(adjustl(Names(g)))//'</div><br>' write(11,*) ' <div style="font-size: 1.5em;">Available Subsections : </div><br> <div id="SubSectionBar"></div><br>' write(11,*) '<table border="0" width="100%" cellpadding="0" cellspacing="0" >' write(11,*) '<tr><td width="20%"></td>' write(11,*) '<td>' write(11,*) '<br>' ! write(11,*) ' <div id="PassMenu">' do n=g+1,nbfiles if(Levels(levelandparity(4,g),n) == Levels(levelandparity(4,g),g)) then if(levelandparity(4,n) == 2) then write(11,*) '<br>' write(11,*) '<div id="ContentMenu0"><table border="0" width="100%" cellpadding="0" cellspacing="0" ><tr><td>' ! write(11,*) '<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'>'//'<img src="'//trim(adjustl(fRevArbo(g)))//'pict/b1.png'//'" alt="Under construction" title="Under construction">'//trim(adjustl(Names(n)))//'</a>'//'<br>' write(11,*) '<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'>'//'→ '//trim(adjustl(Names(n)))//'</a>'//'<br>' write(11,*) '</td></tr></table></div>' end if if(levelandparity(4,n) == 3) then write(11,*) '<div id="ContentMenu1"><table border="0" width="100%" cellpadding="0" cellspacing="0" ><tr><td>' ! write(11,*) '<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'>'//'<img src="'//trim(adjustl(fRevArbo(g)))//'pict/b2.png'//'" alt="Under construction" title="Under construction">'//trim(adjustl(Names(n)))//'</a>'//'<br>' write(11,*) '<a href='//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(n)))//'>'//'→ '//trim(adjustl(Names(n)))//'</a>'//'<br>' write(11,*) '</td></tr></table></div>' end if else exit end if end do write(11,*) '</td>' write(11,*) '<td width="20%"></td>' write(11,*) '</tr>' write(11,*) '</table>' ! write(11,*) ' </div>' close(11) end if end if open(11,file=trim(adjustl(fFileArbo(g))),POSITION='APPEND') write(11,*) ' <br>' write(11,*) ' </td>' write(11,*) ' <td style="width: 2%;" > </td>' write(11,*) ' </table>' write(11,*) ' </td>' write(11,*) ' <td style="width: 5%; "></td>' write(11,*) ' </tr>' write(11,*) ' </table>' write(11,*) ' </div>' write(11,*) '' write(11,*) '<!--' write(11,*) '+---------------------+' write(11,*) '| FOOT PAGE |' write(11,*) '+---------------------+' write(11,*) '-->' write(11,*) '' write(11,*) ' <div id="PageFoot">' write(11,*) ' <ul>' do gg=1,nbfiles if(trim(adjustl(Arbo(gg))) == "index") write(11,*) ' <li> <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(gg)))//'">Home</a> </li>' if(trim(adjustl(Arbo(gg))) == "About") write(11,*) ' <li> <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(gg)))//'">Contact</a> </li>' if(trim(adjustl(Arbo(gg))) == "About") write(11,*) ' <li> <a href="'//trim(adjustl(fRevArbo(g)))//trim(adjustl(fFileArbo(gg)))//'">About</a> </li>' end do ! write(11,*) ' <li> <a href="#">Home</a> </li>' ! write(11,*) ' <li> <a href="#">Contact</a> </li>' ! write(11,*) ' <li> <a href="#">About</a> </li>' write(11,*) ' </ul>' write(11,*) ' </div>' write(11,*) '' write(11,*) '</BODY>' write(11,*) '</HTML>' end do ! Generating sitemap.xml call system("echo '"//'<?xml version="1.0" encoding="UTF-8"?>'//"' > "//'sitemap.xml') open(11,file='sitemap.xml',POSITION='APPEND') write(11,*) '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' do g=1,nbfiles write(11,*) ' <url>' write(11,*) ' <loc>'//'http://spheniscus.brennik.fr/'//trim(adjustl(fFileArbo(g)))//'</loc>' write(11,*) ' <lastmod>'//year//'-'//month//'-'//day//'</lastmod>' write(11,*) ' <changefreq>'//'weekly'//'</changefreq>' write(11,*) ' <priority>'//'1'//'</priority>' write(11,*) ' </url>' end do close(11) call system('echo '//'"</urlset>"'//' >> '//'sitemap.xml') end program staticgen