/* 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; }