2010-06-04 9 views
3

Comment puis-je déterminer le type mime d'un fichier (dans OCaml)?Détermination du type mime d'un fichier

J'essaie de définir la langue pour un contrôle GtkSourceView, mais pour ce faire, je dois d'abord déterminer la langue. La seule façon que je peux voir de le faire est d'utiliser le type MIME - il y a une fonction qui retourne la langue correcte comme suit:

GSourceView.source_languages_manager#get_language_from_mime_type : string -> source_language option 

Je ne veux vraiment pas coder en dur la langue dans ma source . S'il n'est pas possible de déterminer le type mime dans OCaml (et je n'ai pas encore trouvé de chemin, après avoir parcouru la documentation), y a-t-il peut-être une autre façon de déterminer la langue source?

Répondre

3

La plupart des langues manquent de cela, donc je serais très surpris de le trouver dans OCaml. Apache le fait avec un fichier mime.types - vous pouvez y chercher des indices. C'est la façon la plus habituelle - une énorme table qui mappe les extensions en mimetypes. Vous pouvez le mettre en œuvre en OCaml facilement:

let mimetype_of_extension = function 
    | "txt" | "log" -> "text/plain" 
    | "html" | "htm" -> "text/html" 
    | "zip" | "application/zip" 
... 

Une autre façon est de regarder le contenu du fichier, mais vous avez besoin essentiellement de connaître les différents formats de fichiers. Cela dit, cela ne vous aide pas beaucoup, puisque les fichiers sources de toutes les langues sont normalement traités comme text/plain. Ils ne sont pas reconnaissables par le type mime; et donc je n'ai aucune idée de ce que fait votre fonction get_language_from_mime_type.

Cependant, le nom de fichier extensions de divers fichiers source sont plus ou moins standardisés, donc si vous connaissez l'extension, vous connaîtrez la langue. Obtenir l'extension est aussi simple que d'extraire tout ce qui suit la dernière période du nom de fichier.

let extension_of_filename filename = 
    let pos = (String.rindex filename '.') + 1 in 
    let len = String.length filename in 
    let ext = String.create (len - pos) in 
    String.blit filename pos ext 0 (len - pos); 
    ext;; 

Eh bien, d'accord, simple dans toutes les langues sauf Brainfuck et OCaml, au moins. Après cela, c'est facile - "c" est un programme C, comme "h"; "ml" est OCaml;

+2

L'OP a déjà une dépendance sur GtkSourceView, donc il veut probablement une fonction qui retourne un type listé dans .../share/mime/types, qui est installé par GtkSourceView ou l'une de ses dépendances. Ce fichier liste "text/x-erlang", "text/x-eiffel", etc (juste en passant par les "e" s :) :) Il n'y a pas d'extensions canoniques pour ces types listés dans ce fichier cependant. –

+1

Je pense que get_language_from_mime_type est pour finir obtenir une description syntaxique (en surbrillance, ...) de l'un des fichiers de configuration eiffel.lang, erlang.lang, ... dans .../share/gtksourceview-2.0/language-specs/ –

+0

@PascalCuoq - Votre droite, ce sont les types mime que je veux rechercher - cela signifie-t-il que je vais devoir créer moi-même une grande table de recherche, et retourner le type mime basé sur l'extension de fichier? –

3

Après avoir étudié le code source de gedit, qui inclut cette fonctionnalité, j'ai découvert une méthode dans glib qui va le faire pour moi. This answer fournit un exemple d'utilisation de la méthode g_file_info_get_content_type(). Il y a aussi la méthode g_content_type_get_mime_type(), qui est aussi disponible en glib.

Malheureusement, il n'y a pas encore de retour à la ligne pour ces fonctions, ce qui signifie que je devrais générer mon propre habillage.

2

Dans GTK, vous pouvez envelopper les fonctions que vous avez déjà trouvées.

Il n'est également pas difficile d'analyser /etc/mime.types - c'est un simple fichier séparé par des espaces. Je crois que Ocsigen et Ocamlnet contiennent du code pour ce faire, mais je ne sais pas si elles facilitent l'accès (par exemple, une fonction exposée par la bibliothèque Ocamlnet netstring).

1

Ce n'est probablement pas la meilleure méthode pour déterminer le type de code source (l'utilisation de /etc/mime.types est la meilleure pour cet IMO), mais vous pouvez également utiliser OCaml bindings for libmagic.

Questions connexes