Add related words to Anki cards. Break line if any reference is provided.
# To build dictionary you need to install:
#
# $ sudo apt-get install dictfmt
#
# Available target:
#
# all build dictionaries
# install install dictionaries, so they been available in stardict, may require root permission
# uninstall remove dictionaries, they been unavailable in stardict, may require root permission
#
# You can override such variables in Makefile.config:
#
# SF_USER SourceForge user name.
# prefix Prefix to install path.
################################################################
# Standard GNU Makefile settings.
SHELL = /bin/bash
export PATH := /bin:/usr/bin:${PATH}
# Disable built in pattern rules.
MAKEFLAGS += -r
# Disable built in variables.
MAKEFLAGS += -R
# Disable built in suffix rules.
.SUFFIXES:
# Delete target file if command fails.
.DELETE_ON_ERROR:
# Default target.
.DEFAULT_GOAL = help
################################################################
# Build script definitions.
BUILD_SCRIPTS := $(firstword $(MAKEFILE_LIST))
ifneq '' '$(wildcard Makefile.config)'
include Makefile.config
BUILD_SCRIPTS += Makefile.config
endif
################################################################
# Version extracting/generation.
VER_FILE := VERSION
# Prevent making distribution with wrong version.
ifneq '' '$(filter deploy% dist%,$(MAKECMDGOALS))'
ifeq '' '$(MAKE_RESTARTS)'
$(shell rm -f $(VER_FILE))
endif
endif
# Here are vmajor and vminor. Look README section "Versioning rules."
-include $(VER_FILE)
$(VER_FILE): | $(dir $(VER_FILE))
\
[ -d .hg/ ] || { echo We miss VERSION file!!; exit 0; }; \
vtagdist=$$(hg log -r . --template '{latesttagdistance}'); \
vatrelease=$$([ $$vtagdist -le 1 ] && echo yes || echo no); \
vtag=$$(hg log -r . --template '{latesttag}'); \
vmajor=$${vtag#v}; \
vmajor=$${vmajor%%.*}; \
vminor=$${vtag#*.}; \
vrev=$$(hg id -i); \
visclean=$$(case $$vrev in *+) echo no;; *) echo yes;; esac); \
vrev=$${vrev%+}; \
{ \
echo "vrev=$$vrev"; \
echo "vtag=$$vtag"; \
echo "vtagdist=$$vtagdist"; \
echo "visclean=$$visclean"; \
echo "vatrelease=$$vatrelease"; \
echo "vmajor=$$vmajor"; \
echo "vminor=$$vminor"; \
} >$@
################################################################
# Determine platform/environment.
host_os = unix
ifneq '' '$(COMSPEC)'
ifneq '' '$(WINDIR)'
# Probably under Windows.
host_os = windows
ifneq '' '$(wildcard /etc/setup/*cygwin*)'
# Probably under Cygwin.
host_os = cygwin
endif
endif
endif
################################################################
# Build tools definition/switches.
INSTALL = install
INSTALL_PROGRAM = $(INSTALL)
INSTALL_DATA = $(INSTALL) -m 644
RST_WARNING_FLAGS := --halt warning
RST_FLAGS := --strip-comments
RST_FLAGS += $(RST_WARNING_FLAGS)
RST2HTML := rst2html
ifeq '$(host_os)' 'cygwin'
RST2HTML := rst2html.py
endif
RST2HTML_RENDER_FLAGS := --strip-comments --embed-stylesheet --no-xml-declaration --math-output=HTML --initial-header-level=2
RST2HTML_FLAGS := $(RST_FLAGS) $(RST2HTML_RENDER_FLAGS)
LATEX2PDF := pdflatex
################################################################
# Install paths.
ifeq '$(origin prefix)' 'undefined'
ifeq '$(shell id -u)' '0'
prefix = /usr/local
else
prefix = $(HOME)/usr
endif
endif
datarootdir := $(prefix)/share
datadir := $(datarootdir)/dictd
elispdir := $(datarootdir)/emacs/site-lisp
################################################################
# Project dirs/files.
pkgname = gadict
fullpkgname = $(pkgname)-$(vmajor).$(vminor)
PY_FILES := $(wildcard py/gadict*.py)
GADICT_FILES := $(wildcard *.gadict)
C5_FILES := dist/dictd/gadict_en-ru+uk.c5 dist/dictd/gadict_voa.c5
ALL_C5_FILES := $(C5_FILES) dist/dictd/gadict_en-ru.c5 dist/dictd/gadict_en-uk.c5
DICT_FILES := $(C5_FILES:.c5=.dict)
DICTDZ_FILES := $(C5_FILES:.c5=.dict.dz)
INDEX_FILES := $(C5_FILES:.c5=.index)
SRS_TAB_FILES := $(patsubst %.gadict,dist/srs/%.tab.txt,$(GADICT_FILES))
SRS_ANKI_FILES := $(patsubst %.gadict,dist/srs/%.apkg,$(GADICT_FILES))
RST_TMPL_FILE = dist/misc/rst.tmpl
RST_CSS_FILE = www/tmpl/rst.css
RST_FILES := $(wildcard www/*.rst)
RST_HTML_FILES := $(patsubst www/%.rst,dist/www/%.html,$(RST_FILES))
INDEX_HTML_FILE := dist/www/index.html
STAT_RST_FILE := dist/misc/STAT.rst
STAT_HTML_FILE := dist/www/STAT.html
HTML_FILES := $(RST_HTML_FILES) $(INDEX_HTML_FILE) $(STAT_HTML_FILE)
LOGO_NAME := logo
LOGO_SVG := $(LOGO_NAME).svg
LOGO_DIM := 32x32 48x48 64x64
LOGO_PNG_FILES := $(patsubst %,$(LOGO_NAME)-%.png,$(LOGO_DIM))
DISTREL_TARBALLS = dist/$(fullpkgname).tar.gz dist/$(fullpkgname).zip
DISTSRC_TARBALLS = dist/$(fullpkgname)_src.tar.gz # dist/$(fullpkgname)_src.zip
################################################################
# Deploy/release targets.
.PHONY: deploy
deploy: deploy2defun deploy2sf
.PHONY: deploy-hg
deploy-hg: deploy2defun-hg deploy2sf-hg
.PHONY: release
release: release2defun release2sf
.PHONY: release2defun
release2defun: validate-release deploy2defun
.PHONY: release2sf
release2sf: validate-release deploy2sf
DEFUN_USER ?= user
DEFUN_HG_SRV ?= hg.defun.work
DEFUN_HG_DIR ?= /srv/hg/gadict
DEFUN_WWW_SRV ?= defun.work
DEFUN_WWW_DIR ?= /srv/www/gadict
DEFUN_REL_DIR ?= /srv/www/gadict/download
.PHONY: deploy2defun
deploy2defun: deploy2defun-www deploy2defun-dist deploy2defun-hg
.PHONY: deploy2defun-hg
deploy2defun-hg:
hg push ssh://$(DEFUN_USER)@$(DEFUN_HG_SRV)/$(DEFUN_HG_DIR) || [ $$? = 1 ]
.PHONY: deploy2defun-www
deploy2defun-www: $(HTML_FILES)
( \
echo 'cd $(DEFUN_WWW_DIR)'; \
for f in $(HTML_FILES); do \
n=$${f##*/}; \
echo "put $$f $$n"; \
echo "chmod 644 $$n"; \
done; \
echo 'quit'; \
) | sftp -b - $(DEFUN_USER)@$(DEFUN_WWW_SRV)
.PHONY: deploy2defun-dist
deploy2defun-dist: $(DISTREL_TARBALLS) $(DISTSRC_TARBALLS)
( \
echo "-mkdir $(DEFUN_REL_DIR)"; \
echo "-mkdir $(DEFUN_REL_DIR)/v$(vmajor).$(vminor)"; \
echo "cd $(DEFUN_REL_DIR)/v$(vmajor).$(vminor)"; \
for f in $(DISTREL_TARBALLS) $(DISTSRC_TARBALLS); do \
n=$${f##*/}; \
echo "put $$f $$n"; \
echo "chmod 644 $$n"; \
done; \
) | sftp -b - $(DEFUN_USER)@$(DEFUN_WWW_SRV)
SF_USER ?= gavenkoa
# First time you deploy to SourceForge (sf) you need manually login to:
# $ sftp $(SF_USER),$(pkgname)@web.sourceforge.net
# as it may require interactive input for accepting server public key.
# Next time any action fully automated.
.PHONY: deploy2sf
deploy2sf: deploy2sf-www deploy2sf-dist deploy2sf-voa deploy2sf-hg
.PHONY: deploy2sf-hg
deploy2sf-hg:
hg push ssh://$(SF_USER)@hg.code.sf.net/p/$(pkgname)/code || [ $$? = 1 ]
# Will be accessed via http://$(pkgname).sourceforge.net
.PHONY: deploy2sf-www
deploy2sf-www: $(HTML_FILES)
( echo 'cd htdocs'; \
for f in $(HTML_FILES); do \
n=$${f##*/}; \
echo "put $$f $$n"; \
echo "chmod 644 $$n"; \
done; \
echo 'quit'; \
) | sftp -b - $(SF_USER),$(pkgname)@web.sourceforge.net
.PHONY: deploy2sf-voa
deploy2sf-voa: voa
( echo 'cd htdocs'; \
echo "put voa-special.pdf"; \
echo "chmod 644 voa-special.pdf"; \
echo 'quit'; \
) | sftp -b - $(SF_USER),$(pkgname)@web.sourceforge.net
.PHONY: deploy2sf-dist
deploy2sf-dist: $(DISTREL_TARBALLS) $(DISTSRC_TARBALLS)
( echo 'cd /home/frs/project/$(shell v=$(pkgname); echo $${v:0:1}/$${v:0:2})/$(pkgname)'; \
echo "put www/README.rst"; \
echo "chmod 644 README.rst"; \
echo "-mkdir v$(vmajor).$(vminor)"; \
echo "cd v$(vmajor).$(vminor)"; \
for f in $(DISTREL_TARBALLS) $(DISTSRC_TARBALLS); do \
n=$${f##*/}; \
echo "put $$f $$n"; \
echo "chmod 644 $$n"; \
done; \
echo 'quit'; \
) | sftp -b - $(SF_USER),$(pkgname)@frs.sourceforge.net
.PHONY: validate-release
validate-release:
\
case ${visclean} in \
no) echo "Local changes found. Build stop."; \
exit 1;; \
esac
\
case $(vatrelease) in \
no) echo "We are not at release. Build stop."; \
exit 1;; \
esac
################################################################
# Dist targets.
.PHONY: dist
dist: dist-rel dist-src
.PHONY: dist-rel
dist-rel: $(DISTREL_TARBALLS)
DISTREL_DICTDZ_FILES := $(patsubst %,dist/$(fullpkgname)/dictd/%,$(notdir $(DICTDZ_FILES)))
DISTREL_INDEX_FILES := $(patsubst %,dist/$(fullpkgname)/dictd/%,$(notdir $(INDEX_FILES)))
DISTREL_RST_FILES := $(patsubst %,dist/$(fullpkgname)/doc/txt/%,$(notdir $(RST_FILES)))
DISTREL_HTML_FILES := $(patsubst %,dist/$(fullpkgname)/doc/html/%,$(notdir $(RST_HTML_FILES)))
DISTREL_SRS_TAB_FILES := $(patsubst %,dist/$(fullpkgname)/srs/%,$(notdir $(SRS_TAB_FILES)))
DISTREL_SRS_ANKI_FILES := $(patsubst %,dist/$(fullpkgname)/srs/%,$(notdir $(SRS_ANKI_FILES)))
dist/$(fullpkgname).tar.gz: $(DISTREL_DICTDZ_FILES) $(DISTREL_INDEX_FILES) $(DISTREL_SRS_TAB_FILES) $(DISTREL_SRS_ANKI_FILES) $(DISTREL_RST_FILES) $(DISTREL_HTML_FILES) $(BUILD_SCRIPTS)
rm -rf $@
tar zcf $@ -C dist/ $(fullpkgname)
dist/$(fullpkgname).zip: $(DISTREL_DICTDZ_FILES) $(DISTREL_INDEX_FILES) $(DISTREL_RST_FILES) $(DISTREL_HTML_FILES) $(BUILD_SCRIPTS)
rm -rf $@
cd $(dir $@) && zip -r $(notdir $@) $(fullpkgname)
$(DISTREL_DICTDZ_FILES) $(DISTREL_INDEX_FILES): dist/$(fullpkgname)/dictd/%: dist/dictd/% | dist/$(fullpkgname)/dictd/
cp $< $@
$(DISTREL_SRS_TAB_FILES): dist/$(fullpkgname)/srs/%: dist/srs/% | dist/$(fullpkgname)/srs/
cp $< $@
$(DISTREL_SRS_ANKI_FILES): dist/$(fullpkgname)/srs/%: dist/srs/% | dist/$(fullpkgname)/srs/
cp $< $@
$(DISTREL_RST_FILES): dist/$(fullpkgname)/doc/txt/%: www/% | dist/$(fullpkgname)/doc/txt/
cp $< $@
$(DISTREL_HTML_FILES): dist/$(fullpkgname)/doc/html/%: dist/www/% | dist/$(fullpkgname)/doc/html/
cp $< $@
$(patsubst %,dist/$(fullpkgname)/%, dictd/ srs/ doc/txt/ doc/html/):
mkdir -p $@
.PHONY: dist-src
dist-src: $(DISTSRC_TARBALLS)
DISTSRC_GADICT_FILES := $(patsubst %,dist/$(fullpkgname)_src/%,$(GADICT_FILES))
DISTSRC_PY_FILES := $(patsubst %,dist/$(fullpkgname)_src/py/%,$(notdir $(PY_FILES)))
DISTSRC_RST_FILES := $(patsubst %,dist/$(fullpkgname)_src/www/%,$(notdir $(RST_FILES)))
DISTSRC_TMPL_FILES := $(patsubst %,dist/$(fullpkgname)_src/www/tmpl/%, rst.css rst.tmpl.in)
DISTSRC_BUILD_SCRIPTS := $(patsubst %,dist/$(fullpkgname)_src/%, Makefile VERSION)
dist/$(fullpkgname)_src.tar.gz: $(DISTSRC_GADICT_FILES) $(DISTSRC_PY_FILES) $(DISTSRC_RST_FILES) $(DISTSRC_TMPL_FILES) $(DISTSRC_BUILD_SCRIPTS) $(BUILD_SCRIPTS)
rm -rf $@
tar zcf $@ -C dist/ $(fullpkgname)_src
$(DISTSRC_GADICT_FILES): dist/$(fullpkgname)_src/%: % | dist/$(fullpkgname)_src/
cp $< $@
$(DISTSRC_PY_FILES): dist/$(fullpkgname)_src/py/%: py/% | dist/$(fullpkgname)_src/py/
cp $< $@
$(DISTSRC_RST_FILES): dist/$(fullpkgname)_src/www/%: www/% | dist/$(fullpkgname)_src/www/
cp $< $@
$(DISTSRC_TMPL_FILES): dist/$(fullpkgname)_src/www/tmpl/%: www/tmpl/% | dist/$(fullpkgname)_src/www/tmpl/
cp $< $@
$(DISTSRC_BUILD_SCRIPTS): dist/$(fullpkgname)_src/%: % | dist/$(fullpkgname)_src/
cp $< $@
dist/$(fullpkgname)_src/ $(patsubst %,dist/$(fullpkgname)_src/%, py/ www/ www/tmpl/):
mkdir -p $@
################################################################
# Build targets.
.PHONY: all
all: dict
.PHONY: dict dictd c5
dictd c5: dict
dict: $(DICTDZ_FILES) $(INDEX_FILES)
# --case-sensitive
dist/dictd/%.dict dist/dictd/%.index: dist/dictd/%.c5 dist/dictd/%.c5.name dist/dictd/%.c5.url $(MAKEFILE_LIST)
(cd dist/dictd; dictfmt -c5 --headword-separator '; ' --break-headwords --utf8 --allchars -s "`cat $*.c5.name`" -u "`cat $*.c5.url`" $*) < $<
dist/dictd/%.dict.dz: dist/dictd/%.dict
dictzip -c $< >$@
GADICT_SUFFIXES := en-ru+uk en-ru en-uk voa
.SECONDARY: $(patsubst %,dist/dictd/gadict_%.c5.name,$(GADICT_SUFFIXES))
.SECONDARY: $(patsubst %,dist/dictd/gadict_%.c5.url,$(GADICT_SUFFIXES))
dist/dictd/%.c5.name dist/dictd/%.c5.url: dist/dictd/%.c5
:
# -B suppress __pycache__ dir
dist/dictd/gadict_en-ru+uk.c5: gadict_en-ru+uk.gadict py/gadict.py py/gadict_c5.py | dist/dictd/
python3 -B py/gadict_c5.py $< $@
dist/dictd/gadict_en-ru.c5: gadict_en-ru+uk.gadict py/gadict.py py/gadict_c5.py | dist/dictd/
python3 -B py/gadict_c5.py $< $@ ru
echo "gadict En-Ru"> dist/dictd/gadict_en-ru.c5.name
dist/dictd/gadict_en-uk.c5: gadict_en-ru+uk.gadict py/gadict.py py/gadict_c5.py | dist/dictd/
python3 -B py/gadict_c5.py $< $@ uk
echo "gadict En-Uk"> dist/dictd/gadict_en-uk.c5.name
dist/dictd/gadict_voa.c5: gadict_voa.gadict py/gadict.py py/gadict_c5.py | dist/dictd/
python3 -B py/gadict_c5.py $< $@ en
dist/dictd/:
mkdir -p $@
.PHONY: srs
srs: $(SRS_ANKI_FILES) $(SRS_TAB_FILES)
.PHONY: anki
anki: $(SRS_ANKI_FILES)
dist/srs/%.apkg: %.gadict py/gadict.py py/gadict_srs_anki.py $(MAKEFILE_LIST) | dist/srs/
PYTHONPATH=/usr/share/anki: python -B py/gadict_srs_anki.py $< $@
dist/srs/gadict_en-ru+uk.tab.txt: gadict_en-ru+uk.gadict py/gadict.py py/gadict_srs_tab.py $(MAKEFILE_LIST) | dist/srs/
python3 -B py/gadict_srs_tab.py $< $@ ru,uk
dist/srs/gadict_voa.tab.txt: gadict_voa.gadict py/gadict.py py/gadict_srs_tab.py $(MAKEFILE_LIST) | dist/srs/
python3 -B py/gadict_srs_tab.py $< $@
dist/srs/:
mkdir -p $@
################################################################
# Install/uninstall targets.
.PHONY: install
install: $(DICTDZ_FILES) $(INDEX_FILES)
mkdir -p $(datadir) $(elispdir)
for f in $(DICTDZ_FILES) $(INDEX_FILES); do \
$(INSTALL_DATA) $$f $(datadir); \
done
$(INSTALL_DATA) contrib/gadict.el $(elispdir)
emacs -batch -f batch-byte-compile $(elispdir)/gadict.el
OLD_DICT_FILES := gadict-abbr.dict-c5 gadict-adjective-en-ru.dict-c5 \
gadict-adverb-en-ru.dict-c5 gadict-conjunction-en-ru.dict-c5 \
gadict-en-ru.dict-c5 gadict-irregular-verbs-en-ru.dict-c5 \
gadict-numeral-en-ru.dict-c5 gadict-phrasal-verbs-en-ru.dict-c5 \
gadict-preposition-en-ru.dict-c5 gadict-pronoun-en-ru.dict-c5 \
gadict-regular-verbs-en-ru.dict-c5
OLD_DICTDZ_FILES := $(OLD_DICT_FILES:.dict-c5=.dict.dz)
OLD_INDEX_FILES := $(OLD_DICT_FILES:.dict-c5=.index)
.PHONY: uninstall
uninstall:
for f in $(DICTDZ_FILES) $(INDEX_FILES); do \
rm -f $(datadir)/$$f; \
done
for f in $(OLD_DICTDZ_FILES) $(OLD_INDEX_FILES); do \
rm -f $(datadir)/$$f; \
done
rm -f $(elispdir)/gadict.el $(elispdir)/gadict.elc
################################################################
# Documentation targets.
.PHONY: docs
docs: html
.PHONY: html
html: $(HTML_FILES)
$(INDEX_HTML_FILE): dist/www/README.html
cp $< $@
$(RST_HTML_FILES): dist/www/%.html: www/%.rst $(RST_CSS_FILE) $(RST_TMPL_FILE) $(BUILD_SCRIPTS) | dist/www/
$(RST2HTML) $(RST2HTML_FLAGS) --stylesheet=$(RST_CSS_FILE) --template=$(RST_TMPL_FILE) www/$*.rst $@
dist/www/:
mkdir -p $@
$(RST_TMPL_FILE): www/tmpl/rst.tmpl.in $(BUILD_SCRIPTS) | $(dir $(RST_TMPL_FILE))
\
[[ "${visclean}" = no ]] && warn1='<b>Warning</b>: Build done with local changes!' || :; \
[[ -z "${visclean}" ]] && warn1='<b>Warning</b>: Build done without <b>VERSION</b> file!' || :; \
[[ "${vatrelease}" = no ]] && warn2='<b>Warning</b>: Build is far from latest <tt>$(vtag)</tt> release state by $(vtagdist) changes.' || :; \
sed -e "s|{date}|$$(date +%F)|" -e "s|{rev}|$$(hg id -i)|" -e "s|{warn1}|$$warn1|" -e "s|{warn2}|$$warn2|" <$< >$@
################################################################
# Article statistics.
.PHONY: stat
stat: $(STAT_HTML_FILE)
$(STAT_HTML_FILE): $(STAT_RST_FILE) $(RST_CSS_FILE) $(RST_TMPL_FILE) | $(dir $(STAT_HTML_FILE))
$(RST2HTML) $(RST2HTML_FLAGS) --stylesheet=$(RST_CSS_FILE) --template=$(RST_TMPL_FILE) $< $@
$(STAT_RST_FILE): $(GADICT_FILES) $(BUILD_SCRIPTS) | $(dir $(STAT_RST_FILE))
{ \
echo '==========================='; \
echo ' gadict project statistics'; \
echo '==========================='; \
echo '.. contents::'; \
echo ' :local:'; \
echo; \
echo "Entries count"; \
echo "============="; \
echo; \
echo '.. class:: right'; \
echo; \
echo '=================================== ======='; \
echo ' Dictionary Entries'; \
echo '=================================== ======='; \
total=0; \
for dic in $(GADICT_FILES); do \
cnt=`grep '^__' $$dic | wc -l`; \
printf '%35s %7s\n' $${dic%.dict-c5} $$cnt; \
total=$$(($$total + $$cnt)); \
done; \
printf '%35s %7s\n' '**Total**' $$total; \
echo '=================================== ======='; \
echo; \
echo "Translations count"; \
echo "=================="; \
echo; \
echo '.. class:: right'; \
echo; \
echo '==================== ============'; \
echo ' gadict_en-ru+uk Translations'; \
echo '==================== ============'; \
ru_tr=`grep '^ru: ' gadict_en-ru+uk.gadict | wc -l`; \
uk_tr=`grep '^uk: ' gadict_en-ru+uk.gadict | wc -l`; \
printf '%20s Ru\n' $$ru_tr; \
printf '%20s Uk\n' $$uk_tr; \
echo '==================== ============'; \
} >$@
dist/misc/:
mkdir -p $@
################################################################
# Misc targets.
.PHONY: logo
logo: logo-png
.PHONY: logo-png
logo-png: $(LOGO_PNG_FILES)
# Require:
# $ sudo apt-get install imagemagick librsvg2-bin
$(LOGO_PNG_FILES): $(LOGO_NAME)-%.png: $(LOGO_SVG)
convert +antialias -background transparent $< -resize $* $@
.PHONY: voa
voa: voa-special.pdf
voa-special.pdf: contrib/voa-special.tex
$(LATEX2PDF) -output-directory . $<
################################################################
# Helpers targets.
.PHONY: help
help:
@\
echo; \
echo Current configuration:; \
echo; \
sed 's=^= =' <$(VER_FILE)
@if [ -f Makefile.config ]; then \
echo; \
echo User configuration:; \
echo; \
sed 's=^= =' <Makefile.config; \
fi
@\
echo; \
echo Supported targets:; \
echo; \
sed -n -e '/^[[:alnum:]_-]*:/{s=^\(.*\):.*= \1=;p;}' $(BUILD_SCRIPTS)
.PHONY: todo
todo:
grep -nH 'TODO\|XXX' $(RST_FILES) $(C5_FILES)
.PHONY: logo-png
logo-png: logo-64x64.png
# Require:
# $ sudo apt-get install imagemagick librsvg2-bin
%.png: %.svg
convert +antialias -background transparent $< $@
################################################################
# Clean targets.
.PHONY: distclean
distclean: clean
rm -rf $(VER_FILE)
.PHONY: clean
clean:
rm -rf dist/