Skip to content

Instantly share code, notes, and snippets.

@douglasduteil
Last active December 16, 2015 12:29
Show Gist options
  • Save douglasduteil/5435289 to your computer and use it in GitHub Desktop.
Save douglasduteil/5435289 to your computer and use it in GitHub Desktop.
Guide de démarrage pour la création de parsers sous ParserCliff v0.0.3 !

ParserCliff version 0.0.3

ParserCliff est une plateforme d'exécution de parsers. Elle permet l'intégration de vos propres parsers, leurs exécutions sur un texte de votre choix, et l'exportation du résultat obtenu (sous XML).

Utilisation

ParserCliff peut être lancé à partir d'un serveur ou localement grâce à Node WebKit

Sur serveur local sous linux

Executer

$ python -m SimpleHTTPServer 8080

ou

$ php -S localhost:8080

Pour y accéder à l'adresse : localhost:8080
ParcerCliff fonction uniquement sous Chromium/Chrome

Sur node-webkit

Télécharger la dernière version de Node WebKit.
Puis suivez le «How to run apps» avec la racine du projet.

Structure générale.

ParserCliff est une application HTML 5 propulsée par AngularJS, RequireJS et CodeMirror.

L'architecture globale de l'application tournes autour de quatre points :

  • la structure de l'application est dans le fichier index.html,
  • le cœur de l'application est dans le dossier core,
  • les ressources statiques sont dans le dossier assets
  • les parsers utilisés par l'application sont dans le dossier parsers

Le management des parsers

Chaque parsers doit :

  • avoir son propre dossier dans le dossier parsers
  • avoir un fichier fichier main.js et un fichier manifest.json valide (voir ci après)
  • doit être présent dans la liste le fichier preferences.json et décrie comme actif pour fonctionner.

Création de parsers.

On prendra pour exemple le parser pAllWords, qui met tous les mots dans une balise <W></W>.

Le manifest (version 1)

Les manifest contiennent trois entrées :

  • name : le nom du parser dans l'application. C'est le nom qui figurera dans le menu parsers, par exemple.
  • controllerName : le nom du contrôleur qui exécute le parcage. Ici c'est le nom référencé par AngularJS comme contrôleur (voir ci après).
  • manifest_version : la version du manifest. La version décrite ici est la version 1.
{
    "name" : "All words (\\w)",
    "controllerName" : "pAllWordsCtrl",
    "manifest_version" : 1
}

Le main.js

Le fichier main.js permet de décrire à l'application le traitement à exécuter par le parser. Il est exécuté morceau par morceau au sein de l'application. On peut ainsi intervenir lorsque le fichier est chargé par l'application et lorsque l'on souhaite exécuter le parcage.

Chargement

La première étape utilise la fonction define de RequireJS pour définir et charger le parser.

define(function onLoad() {

  // [...]

  console.log("pAllWordsCtrl Loaded");

});

Enregistrement

La seconde étape est d'enregistrer au sein de AngularJS le contrôleur qui execute le parcage. Ce contrôleur doit impérativement être lié au module 'pc' (pour Parser Ciff). La syntaxe de définition d'un module est la syntaxe native des controller AngularJS.

On note que le service parsingOperationSvc est interne à ParserCliff et permet de faciliter l'exécution de parcage ligne par ligne (voir ci dessous).

angular.module('pc').controller('pAllWordsCtrl', [
	'$scope', 'parsingOperationSvc', function onExecute($scope, parsingOperationSvc) {

	console.log("START pAllWordsCtrl");

	// [...]

}]));

Parcage

Pour le parcage en lui même, on utilise la classe StringStream de CodeMirror. Celle ci permet de se balader dans le texte qu'on lui donne.

Par souci de simplicité, le service parsingOperationSvc met à notre disposition une fonction executeParsingFct qui prend en argument :

  • le texte à parcourir,
  • la fonction qui sera exécutée au cours sur parcage. Cette fonction aura dans son premier argument le flux de texte. Et peut retourner un objet dont la clé tag détermine le nom de la balise qui englobe le texte courant dans le flux.
  • la fonction callback à appeler lorsque le parage est terminé. Cette fonction aura dans son premier argument le texte généré.

Ainsi, pour parser tous les mots, on définit une fonction qui prend un flux comme premièr argument et on utilise les fonctions de la classe StringStream de CodeMirror pour naviguer.

Par defaut, le texte dans l'éditeur sans balise est contenu dans la variable : $scope.inputText. Le text visible dans l'éditeur est contenu dans la variable : $scope.parsedTextModel.

var parseFct = function (s) {
	var ch = s.next(); // On récupère le caractère suivant

	if (ch =='<' && s.match(/^[^>]/)){
	// On saut toutes balises
		s.next();
		return;
	}

	if (ch.match(/[^a-z\u00C0-\u017F]/i)) return; // On saut tous les caractère non alphabétique

	s.match(/^[a-z\u00C0-\u017F]+/i) // On récupère tous les caractère alphabétique
	return {tag: "W"}; // On les met dans une balise <W></W>

};
parsingOperationSvc.executeParsingFct($scope.parsedTextModel, parseFct, 
function callback(str_o){
	$scope.parsedTextModel = str_o;
	// Apply change if it's not already done.
	if (!$scope.$$phase) $scope.$apply();
});

Exemple complet

define(function onLoad() {

  angular.module('pc').controller('pAllWordsCtrl', [
    '$scope', 'parsingOperationSvc', function onExecute($scope, parsingOperationSvc) {

      console.log("START pAllWordsCtrl");


      var parseFct = function (s) {
        var ch = s.next();

        if (ch =='<' && s.match(/^[^>]/)){
          s.next();
          return;
        }
        
        if (ch.match(/[^a-z\u00C0-\u017F]/i)) return;


        s.match(/^[a-z\u00C0-\u017F]+/i)
        return {tag: "W"};

      };

      parsingOperationSvc.executeParsingFct($scope.parsedTextModel, parseFct, function(str_o){
        $scope.parsedTextModel = str_o;
        // Apply change if it's not already done.
        if (!$scope.$$phase) $scope.$apply();
      });
    }
  ]);

  console.log("pAllWordsCtrl Loaded");

});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment