Skip to content

Commit f9a667c

Browse files
author
Henrik Kjelsberg
committed
Initial commit
0 parents  commit f9a667c

File tree

4 files changed

+287
-0
lines changed

4 files changed

+287
-0
lines changed

Makefile

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
CP=cp
2+
CHMOD=chmod +x
3+
4+
DST:=/usr/local/bin
5+
SRCS=$(wildcard bin/*)
6+
DSTS=$(subst bin,$(DST),$(SRCS))
7+
8+
BOLD=\033[1m
9+
NORMAL=\033[0m
10+
11+
.PHONY: install
12+
13+
$(DST)/%: $(SRCS)
14+
@$(CP) $^ $(DST)
15+
@$(CHMOD) $@
16+
17+
install: $(DSTS)
18+
@echo
19+
@echo "org was installed to $(BOLD)$(DST)$(NORMAL)"
20+
@echo "execute $(BOLD)org --help$(NORMAL) for more information"
21+
@echo
22+
23+
uninstall:
24+
$(RM) $(DSTS)

Readme.org

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
:PROPERTIES:
2+
#+TITLE: Suite of org-mode tools
3+
:END:
4+
5+
I've been using ~org-mode~ a fair amount lately and think I'll convert some of
6+
my prior work into org-files. To that end, I'm creating a few tools to ease the
7+
development of org-files.
8+
9+
For now, there's only the command ~org untangle~. All it does is take a bunch of
10+
files as input and it outputs org-mode with tangling-headers.
11+
12+
Here you see how you could assemble an org-file from this very repository and
13+
output that to ~org.org~.
14+
#+BEGIN_SRC sh
15+
org untangle "$(find bin) Makefile" > org.org
16+
#+END_SRC

bin/org

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
IFS=$' '
4+
5+
version="0.0.1"
6+
cmd=$(basename $0)
7+
8+
#
9+
# Find sub-commands
10+
#
11+
12+
findSubCmds() {
13+
local subcmds=""
14+
for dir in ${PATH//:/ }; do
15+
subcmds="$subcmds $(find $dir -name "$cmd-*" 2> /dev/null)"
16+
done
17+
echo "$subcmds" | tr ' ' '\n' | sort | uniq | xargs -L1 basename
18+
}
19+
20+
#
21+
# List sub-commands
22+
#
23+
24+
listSubCmds(){
25+
local subcmds=$(findSubCmds)
26+
for subcmd in $subcmds; do
27+
local shortusage=$($subcmd __shortusage)
28+
[[ -z "$shortusage" ]] && shortusage="$subcmd"
29+
shortusage=${shortusage/$cmd-/}
30+
printf "%-3s %-25s %s\n" '' "$shortusage" "$($subcmd __description)"
31+
done
32+
}
33+
34+
#
35+
# Output usage
36+
#
37+
38+
usage() {
39+
cat << EOT
40+
41+
Usage: $cmd command [options]
42+
43+
Commands:
44+
45+
help <command> output usage for a specific command
46+
$(listSubCmds)
47+
48+
Options:
49+
50+
-h, --help output usage information
51+
-V, --version output version number
52+
53+
EOT
54+
}
55+
56+
#
57+
# Missing command
58+
#
59+
60+
missingCmd() {
61+
echo
62+
echo " $cmd: '$1' is either misspelled or not installed."
63+
echo
64+
}
65+
66+
67+
#
68+
# Parse arguments
69+
#
70+
71+
args=""
72+
subcmd=""
73+
while test $# -ne 0; do
74+
arg=$1; shift
75+
case $arg in
76+
help)
77+
[ -n $1 ] && subcmd="$cmd-$1"; shift
78+
args="--help"
79+
break;
80+
;;
81+
-h|--help)
82+
usage
83+
exit 0
84+
;;
85+
-V|--version)
86+
echo $version
87+
exit 0
88+
;;
89+
*)
90+
subcmd="$cmd-$arg"
91+
args="$args $@"; shift
92+
break;
93+
;;
94+
esac
95+
done
96+
97+
#
98+
# Sub-command
99+
#
100+
101+
if [[ $($subcmd 2>&1) =~ "command not found" ]]; then
102+
missingCmd "${subcmd##*\-}"
103+
exit $?
104+
fi
105+
106+
$subcmd $args
107+

bin/org-untangle

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
IFS=$'\n\t'
4+
5+
cmd=$(basename $0)
6+
header=true
7+
subdir=
8+
output=
9+
10+
#
11+
# Output usage
12+
#
13+
14+
usage() {
15+
cat << EOT
16+
17+
Usage: ${cmd/-/ } [options] <path ...>
18+
19+
Options:
20+
21+
-h, --help output usage information
22+
-o, --output print to file instead of stdout
23+
-s, --subdir root of entanglement
24+
25+
--no-header skip the global properties-header
26+
27+
EOT
28+
}
29+
30+
#
31+
# Output org-mode header
32+
#
33+
34+
org-header() {
35+
cat <<EOT
36+
:PROPERTIES:
37+
#+EXPORT_EXCLUDE_TAGS: noexport
38+
#+PROPERTY: mkdirp yes
39+
#+PROPERTY: noweb yes
40+
:END:
41+
42+
EOT
43+
}
44+
45+
#
46+
# Output language by extension
47+
#
48+
49+
language() {
50+
local filename=$(basename "$1")
51+
local extension="${filename##*.}"
52+
53+
declare -A languages
54+
languages=(
55+
[c]=c
56+
[clj]=clojure
57+
[cljs]=clojurescript
58+
[edn]=edn
59+
[erlang]=erl
60+
[cpp]=c++
61+
[css]=css
62+
[haskell]=hs
63+
[js]=javascript
64+
[less]=less
65+
[md]=markdown
66+
[python]=py
67+
[ryby]=rb
68+
[sass]=sass
69+
[sh]=shell
70+
)
71+
72+
echo ${languages["$extension"]}
73+
}
74+
75+
#
76+
# Output org-mode source-block
77+
#
78+
79+
org-src() {
80+
local filename=$(basename "$1")
81+
local lang=$(language $filename)
82+
echo "#BEGIN_SRC $lang :tangle $subdir$file"
83+
cat $file
84+
echo "#END_SRC"
85+
echo
86+
}
87+
88+
#
89+
# Output assembled org-mode from a directory recursively
90+
#
91+
92+
untangle() {
93+
local files=$@
94+
[[ $header = true ]] && org-header
95+
echo "* Source :noexport:"
96+
echo
97+
for file in $files; do
98+
org-src "$file"
99+
done
100+
}
101+
102+
#
103+
# Parse arguments
104+
#
105+
106+
while test $# -ne 0; do
107+
arg=$1; shift
108+
case $arg in
109+
__shortusage)
110+
echo "$cmd [options]"
111+
exit 0
112+
;;
113+
__description)
114+
echo "Assembles an org-file from a list of paths"
115+
exit 0
116+
;;
117+
-h|--help)
118+
usage
119+
exit 0
120+
;;
121+
-o|--output)
122+
output=$1; shift
123+
;;
124+
-s|--subdir)
125+
# Ensure that sub-directory ends with a trailing slash
126+
subdir="${1%/}/"; shift
127+
;;
128+
--no-header)
129+
header=false
130+
;;
131+
*)
132+
if [[ -n $output ]]; then
133+
$(untangle $arg > $output)
134+
else
135+
untangle $arg
136+
fi
137+
break;
138+
;;
139+
esac
140+
done

0 commit comments

Comments
 (0)