mirror of
https://github.com/wassname/side-by-side.git
synced 2026-09-10 12:37:06 +08:00
Move source/documents/* to source/
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
angular.module("sideBySide").factory "fetch", ['$http', '$q', 'readerFactory', ($http, $q, readerFactory) ->
|
||||
# Fetch
|
||||
#
|
||||
# @param file [String] Path to config file
|
||||
# @return [Object] Promises and heading
|
||||
(file = "/config.json") ->
|
||||
$http.get(file).then (config) ->
|
||||
promises = config.data.files.map (poem) ->
|
||||
$http.get(poem).then (response) ->
|
||||
readerFactory(poem) response.data
|
||||
|
||||
{
|
||||
fetchPoems: $q.all promises
|
||||
heading: config.data.heading
|
||||
active: config.data.active
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,42 @@
|
||||
angular.module("sideBySide").service "poems", ['fetch', (fetch) ->
|
||||
@all = [{
|
||||
meta: {
|
||||
Active: true
|
||||
}
|
||||
content: [{
|
||||
section: 'Loading...'
|
||||
text: 'Please be patient!'
|
||||
}]
|
||||
}]
|
||||
@heading = undefined
|
||||
|
||||
# Get active poems
|
||||
#
|
||||
# @return [Array] Active poems
|
||||
@getActive = () ->
|
||||
(poem for poem in @all when poem.meta.Active is true)
|
||||
|
||||
# Activize poem based on passed rules
|
||||
#
|
||||
# @param poem [Object]
|
||||
# @param active [Object] { meta: [ 'active', 'values' ] }
|
||||
# @return poem
|
||||
activize = (poem, active) ->
|
||||
poem.meta.Active = true if !active
|
||||
|
||||
for metaKey,values of active
|
||||
poem.meta.Active = true if poem.meta[metaKey] in values
|
||||
|
||||
poem
|
||||
|
||||
# Load poems
|
||||
#
|
||||
# @param base [String]
|
||||
@load = (base = '') =>
|
||||
fetch(base + "/config.json").then (config) =>
|
||||
config.fetchPoems.then (poems) =>
|
||||
@all = (activize(poem, config.active) for poem in poems)
|
||||
@heading = config.heading
|
||||
|
||||
@
|
||||
]
|
||||
@@ -0,0 +1,15 @@
|
||||
angular.module("sideBySide").factory "readerFactory", ['$injector', ($injector) ->
|
||||
# Create poem reader based on file name
|
||||
#
|
||||
# @param [String] Source file name
|
||||
# @return [Object] Reader
|
||||
(filename) ->
|
||||
extension = filename.split(".").pop()
|
||||
switch extension
|
||||
when "json"
|
||||
return $injector.get("jsonReader")
|
||||
when "md", "markdown"
|
||||
return $injector.get("markdownReader")
|
||||
else
|
||||
throw "Unknown extension '" + extension + "'."
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
angular.module("sideBySide").factory("jsonReader", () ->
|
||||
# Read json poem
|
||||
#
|
||||
# For sample input, see:
|
||||
# source/documents/tests/services/reader/json.js.coffee
|
||||
#
|
||||
# @param source [String] Json poem
|
||||
# @return [Object] Poem object
|
||||
(source) ->
|
||||
parsed = eval('(' + source + ')')
|
||||
|
||||
for i,verse of parsed.content
|
||||
if typeof(verse) == "string"
|
||||
parsed.content[i] = { section: "", text: verse }
|
||||
else
|
||||
verse.section = "" if "section" not of verse
|
||||
parsed.content[i] = verse
|
||||
|
||||
parsed
|
||||
)
|
||||
@@ -0,0 +1,66 @@
|
||||
angular.module("sideBySide").factory("markdownReader", () ->
|
||||
# Read markdown poem
|
||||
#
|
||||
# For sample input, see:
|
||||
# source/documents/tests/services/reader/markdown.js.coffee
|
||||
#
|
||||
# @param source [String] Markdown poem
|
||||
# @return [Object] Poem object
|
||||
(source) ->
|
||||
# Read meta information from markdown block
|
||||
#
|
||||
# @param block [string] Meta block
|
||||
# @param inlineLexer [Object] Inline markdown lexer
|
||||
# @return [Object] Meta properties
|
||||
readMeta = (text, inlineLexer) ->
|
||||
meta = {}
|
||||
for line in text.split("\n")
|
||||
lexed = inlineLexer.output(line)
|
||||
match = /([^:]*):(.*)/.exec(lexed)
|
||||
meta[match[1].trim()] = match[2].trim()
|
||||
meta
|
||||
|
||||
# Read and remove one section from start of lexed blocks
|
||||
#
|
||||
# @param lexed [Array] Lexed blocks
|
||||
# @return [Array] Section
|
||||
readSection = (lexed, separators) ->
|
||||
items = []
|
||||
while lexed.length > 0
|
||||
break if lexed[0]["type"] in separators
|
||||
items.push(lexed.shift())
|
||||
items
|
||||
|
||||
# Read content from lexed blocks
|
||||
#
|
||||
# @param lexed [Array] Lexed blocks
|
||||
# @param separators [Array] Section separators
|
||||
# @return [Array] Content
|
||||
readContent = (lexed, separators) ->
|
||||
content = []
|
||||
|
||||
while lexed.length > 0
|
||||
heading = if lexed[0]["type"] in separators \
|
||||
then lexed.shift().text or "" \
|
||||
else ""
|
||||
|
||||
text = readSection(lexed, separators)
|
||||
text.links = lexed.links
|
||||
content.push({
|
||||
section: heading
|
||||
text: marked.parser(text)
|
||||
})
|
||||
content
|
||||
|
||||
marked.setOptions({ smartypants: true })
|
||||
lexed = marked.lexer(source)
|
||||
meta = lexed.shift()
|
||||
meta = readMeta(meta.text, new marked.InlineLexer(lexed.links))
|
||||
separators = if meta.Separator \
|
||||
then [meta.Separator] else ['heading', 'hr']
|
||||
|
||||
{
|
||||
meta: meta
|
||||
content: readContent(lexed, separators)
|
||||
}
|
||||
)
|
||||
@@ -0,0 +1,66 @@
|
||||
angular.module("sideBySide").factory("transformer", () ->
|
||||
# Transform translations
|
||||
#
|
||||
# @param translations [Array] Translations with 'meta' and 'content' keys
|
||||
# @throw No poems or uneven number of verses
|
||||
# @return [Array] Translations transformed into row-based format
|
||||
(translations) ->
|
||||
# Check whether all translations have same number of verses
|
||||
#
|
||||
# @param translations [array] Translations to check
|
||||
checkLengths = (translations) ->
|
||||
if !translations or translations.length < 1
|
||||
throw "No poems found!"
|
||||
lengths = []
|
||||
for translation in translations
|
||||
l = translation.content.length
|
||||
lengths[l] = 0 if l not of lengths
|
||||
lengths[l]++
|
||||
|
||||
# return if all are same length
|
||||
return if _.size(_.compact(lengths)) <= 1
|
||||
|
||||
uneven = (count + " of length " + length \
|
||||
for count,length in lengths \
|
||||
when typeof count isnt "undefined")
|
||||
|
||||
details = []
|
||||
while _.size(_.compact(lengths)) > 1
|
||||
mindex = _.indexOf(lengths, _.min(lengths))
|
||||
maxdex = _.indexOf(lengths, _.max(lengths))
|
||||
|
||||
# least occuring count is higher than most occuring count
|
||||
message = if mindex > maxdex \
|
||||
then "Superfluous verses: " \
|
||||
else "Missing verses after: "
|
||||
|
||||
# get last verses of translations with mindex verses
|
||||
lastVerses = _.map(translations.filter((translation) ->
|
||||
return translation.content.length == mindex
|
||||
), (translation) ->
|
||||
return "'" + _.last(translation.content).text + "'"
|
||||
)
|
||||
|
||||
details.push(message + lastVerses.join(", "))
|
||||
|
||||
# remove least occuring from lengths
|
||||
delete lengths[mindex]
|
||||
|
||||
throw "Poems with uneven number of verses: " +
|
||||
uneven.join(", ") + "." +
|
||||
" (" + details.join("; ") + ")."
|
||||
|
||||
checkLengths(translations)
|
||||
|
||||
data = {
|
||||
meta: (translation.meta for translation in translations)
|
||||
verses: []
|
||||
}
|
||||
|
||||
# columns into rows and rows into columns
|
||||
for i in _.range(translations[0].content.length)
|
||||
data.verses.push(translation.content[i] \
|
||||
for translation in translations)
|
||||
|
||||
data
|
||||
)
|
||||
Reference in New Issue
Block a user