The example presented here shows how one would use groc
to create
an internationalized die-roll application:
$ roll
You rolled a one
$ roll
You rolled a six
Or in Dutch:
$ roll
Je hebt een één gegooid
$ roll
Je hebt een zes gegooid
The project directory is as follows:
├── Makefile
├── lang
│ ├── App.grok
│ ├── en_US.grok
│ └── nl_NL.grok
└── src
└── main.c
The interface file is there simply to specify which functions should be
implemented in each language. In this case, just a simple youRolled()
function:
-- App.grok
interface App
youRolled :: Int -> String
The interface is implemented in two languages: American English
(en_US
) and Netherlandic Dutch (nl_NL
). The standard library modules
"std/English"
and "std/Dutch"
provide several very basic helper
functions. Neither module provides a lexicon of any kind.
English:
-- en_US.grok
lang "en_US"
implements "App"
import "std/English"
App.youRolled(n) = "You rolled " + English.indef(English.spellInt(n))
Dutch:
-- nl_NL.grok
lang "nl_NL"
implements "App"
import "std/Dutch"
App.youRolled(n) = "Je hebt een " + Dutch.spellInt(n) + " gegooid"
The C program implements the main logic. The correct language is automatically selected based on system locale variables.
/* main.c */
#include <grok/rt.h>
#include <rand.h>
#include <stdio.h>
#include <time.h>
int main(void)
{
char *s;
srand(time(NULL));
s = groks("App.youRolled", 1, (rand() % 6) + 1);
printf("%s\n", s);
free(s);
return 0;
}
The grok files are built in the same way C files are built, except using
groc
as the compiler. libgrok-rt
is the grok runtime library.
# Makefile
CC = cc
CFLAGS = -c $(shell pkg-config --cflags grok-rt)
LD = $(CC)
LDFLAGS = $(shell pkg-config --libs grok-rt)
GROC = groc
GROCFLAGS = -c
OBJECTS = src/main.o lang/en_US.o lang/nl_NL.o
TARGET = roll
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(LD) $(LDFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -o $@ $^
%.o: %.grok
$(GROC) $(GROCFLAGS) -o $@ $^
[copied from private communique]
It might be convenient to stick translations into different files, which allows multiple contributors to aid with translation (It works better with things like git) and allows for a greater seperation of concerns. It also cuts down loading a huge file for each translation on init[¿] -- you have a tiny to mediocre-sized file that you can load, parse, and run really quickly on the fly. Meaning that you only load what you use.
Say, you have the following layout: