/*
This file is part of Videos.
Videos is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Videos is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Videos. If not, see .
*/
/*
Programme qui lit un fichier .scn et produit un fichier C++.
Le but est de scripter (coder) le scénario d'une vidéo.
Un fichier scn contient autant du texte (ce qu'on a à dire)
que des commandes C++ permettant de créer des présentations (diapositives)
et des animations.
Le fichier scn permet aussi de télé-commander obs (logiciel de création de vidéo).
Il démarre l'enregistrement, sélectionne la scène (choix de caméra, de saisi d'écran)
etc...
Le résultat de scn-parse est un programme compilable qui contrôle l'exécution du
scénario. Il agit comme télé-souffleur en même temps qu'il pilote les changements
de scènes et de diapositives.
*/
#include
#include
#include
#include
#include
#include
#include
using namespace std;
enum LINE_TYPE{
LINE_TEXT,
LINE_TITLE,
LINE_BULLET,
LINE_SUBBULLET,
LINE_CODE,
LINE_PAUSE,
};
struct TYPE_STRING{
LINE_TYPE type;
string line;
TYPE_STRING(LINE_TYPE _type, PARAM_STRING _line)
: type(_type),line(_line.ptr)
{
}
};
// Enlève les guillemets simples (bug temporaire dans tlmp str_splitlineq)
static string escape_quote(PARAM_STRING line)
{
//return line.ptr;
#if 1
return copystring (line,[](auto &c, auto pt){
if (*pt == '<'){
c.replace(1,"<");
}else if (*pt == '>'){
c.replace(1,">");
}
});
#endif
}
static void print_script (const string &title, const vector &content, int pagenum)
{
// On commence par produire l'appel à telescript() pour toutes les étapes de
// cette diapo. On place des marqueurs entre les étapes.
// On initialise la variable TABUL si il y a un bullet
bool bullet_seen = false;
for (auto &c:content){
if (c.type == LINE_BULLET){
bullet_seen = true;
break;
}
}
printf ("settabul(%s);\n",bullet_seen ? "true" : "false");
printf ("\ttelescript(\"%s\",\n",string_f("[%d] %s",pagenum,title.c_str()).c_str());
bool one_line = false;
for (auto &c:content){
if (is_not_in(c.type,LINE_CODE,LINE_TITLE)){
one_line = true;
if (c.type == LINE_TEXT){
printf ("\t\"${TABUL}%s\\n\"\n",c.line.c_str());
}else if (c.type == LINE_BULLET){
printf ("\t\" -%s\\n\"\n",c.line.c_str());
}else if (c.type == LINE_SUBBULLET){
printf ("\t\" -%s\\n\"\n",c.line.c_str());
}else if (c.type == LINE_PAUSE){
printf ("\t\"##\\n\"\n");
}
}
}
if (!one_line) printf ("\t\"\"\n");
printf ("\t);\n");
// telescript() va produire une fonction bash affichant le texte
// en inscrivant l'étape active
int etape = 0;
for (auto &c:content){
if (c.type == LINE_CODE){
printf ("\t%s\n",c.line.c_str());
}else if (c.type == LINE_TITLE){
const char *pt = c.line.size()>0 ? c.line.c_str() : title.c_str();
printf ("\taddtitle(\"%s\");\n",escape_quote(pt).c_str());
}else if (c.type == LINE_PAUSE){
printf ("\taffiche_etape(%d);\n",etape);
etape++;
}else{
if (c.type == LINE_TEXT){
}else if (c.type == LINE_BULLET){
printf ("\taddbullet(\"%s\");\n",escape_quote(c.line).c_str());
}else if (c.type == LINE_SUBBULLET){
printf ("\taddsubbullet(\"%s\");\n",escape_quote(c.line).c_str());
}
}
}
if (etape == 0) printf ("\taffiche_etape(0);\n");
}
// Retourne vrai si la page pagenum doit être affichée
// Si nopages est vide, on affiche toutes les pages
static bool showpage(const vector &nopages, int pagenum)
{
return nopages.size()==0
|| find(nopages.begin(),nopages.end(),pagenum) != nopages.end();
}
// Assure qu'il y a un LINE_PAUSE à la fin du contenu
static void addpause(vector &content)
{
if (content.size() > 0){
auto &last = content[content.size()-1];
if (last.type != LINE_PAUSE){
content.emplace_back(LINE_PAUSE,"");
}
}
}
int main (int argc, char *argv[])
{
glocal int ret = -1;
glocal const char *incldir = nullptr;
glocal const char *nopages_str = nullptr;
glocal bool listpages = false;
glocal.ret = (argc,argv);
setproginfo ("","0.0","...");
setarg ('i',"incldir","Répertoire contenant les fichiers ressources",glocal.incldir,true);
setarg ('l',"listpages","Affiche l'index de la vidéo",glocal.listpages,false);
setarg ('n',"nopages","Pages à afficher (1,2,...)",glocal.nopages_str,false);
glocal int ret = -1;
glocal vector nopages;
if (glocal.nopages_str != nullptr){
auto tb = str_splitline(glocal.nopages_str,',');
for (auto &s:tb) glocal.nopages.push_back(atoi(s.c_str()));
}
for (int i=0; i content;
glocal bool code = false;
glocal int pagenum = 0;
glocal const char *fname = argv[i];
glocal bool bullet_seen = false;
if (!glocal.listpages){
printf ("#include \"%s/scenario.h\"\n",glocal.incldir);
printf ("#include \"%s/scenario_main.h\"\n",glocal.incldir);
printf ("incldir=\"%s\";\n",glocal.incldir);
}
(glocal.fname,true);
line = str_skip(line);
// On présente toutes les pages ou une seule
bool collect_page = showpage(glocal.nopages,glocal.pagenum);
if (strncmp(line,"--",2)==0){
if (glocal.title.size() > 0){
addpause(glocal.content);
glocal.bullet_seen = false;
if (glocal.listpages){
printf ("[%d] %s\n",glocal.pagenum,glocal.title.c_str());
}else{
if (collect_page) print_script(glocal.title,glocal.content,glocal.pagenum);
}
glocal.pagenum++;
}
glocal.title = line+2;
glocal.content.clear();
glocal.code = false;
}else if (strncmp(line,"-T",2)==0){
glocal.content.emplace_back(LINE_TITLE,str_skip(line+2));
}else if (strncmp(line,"-B",2)==0){
if (glocal.bullet_seen){
glocal.content.emplace_back(LINE_PAUSE,"");
}
glocal.bullet_seen = true;
glocal.content.emplace_back(LINE_BULLET,str_skip(line+2));
}else if (strncmp(line,"-b",2)==0){
glocal.content.emplace_back(LINE_SUBBULLET,str_skip(line+2));
}else if (strncmp(line,"-C",2)==0){
if (collect_page){
glocal.content.emplace_back(LINE_CODE,string_f ("#line %d \"%s\"",noline+1,glocal.fname));
glocal.content.emplace_back(LINE_CODE,str_skip(line+2));
}
}else if (strncmp(line,"-P",2)==0){
if (collect_page){
glocal.content.emplace_back(LINE_PAUSE,"");
}
}else if (strncmp(line,"-/",2)==0){
// Ceci ext un commentaire qui n'apparaitra pas dans le téléscripteur.
}else if (strncmp(line,"-#",2)==0){
glocal.code = !glocal.code;
}else if (glocal.code){
if (line[0] != '\0'){
if (collect_page){
glocal.content.emplace_back(LINE_CODE,string_f ("#line %d \"%s\"",noline+1,glocal.fname));
glocal.content.emplace_back(LINE_CODE,line);
}
}
}else{
glocal.content.emplace_back(LINE_TEXT,line);
}
return 0;
// Dernière diapo
if (glocal.title.size() > 0){
addpause (glocal.content);
if (glocal.listpages){
printf ("[%d] %s\n",glocal.pagenum,glocal.title.c_str());
}else{
bool collect_page = showpage(glocal.nopages,glocal.pagenum);
if (collect_page) print_script(glocal.title,glocal.content,glocal.pagenum);
}
}
if (!glocal.listpages){
printf ("#include \"%s/scenario_main_end.h\"\n",glocal.incldir);
}
if (glocal.some_errors){
glocal.ret = -1;
break;
}else{
glocal.ret = 0;
}
}
return glocal.ret;
return glocal.ret;
}