code - вставка фрагментов кода
Описание
Вставка фрагментов кода из файлов проекта.
Формат:
@@code file=FILENAME part=PARTNAME lang=LANG title=ЗАГОЛОВОК
где:
file- имя файла из проекта, откуда вставлять текст. Может быть абсолютным и относительным (см: Ссылки). Если содержит'#', то считается что указывает на файл с groovy-классом (или java-классом) для генерации текста файла (см: Генерация файлов для вставки). Кроме того, может быть именем класса.part- имя поименнованного фрагмента из файла (см. ниже). Если не указан, вставляется весь текст файлаlang- имя языка для подсветки синтаксиса. Если не указано, определяется по расширению файлаtitle- заголовок. Обычно тут указывается имя файла.mode- режим вывода при генерации (см: Генерация файлов для вставки).
Особые соглашения по имени файла:
- если файл не абсолютный (не имеет
/в начале), то он последовательно ищется в каталогах:_inc/ИМЯ-ФАЙЛА-СТАТЬИ_inc/ИМЯ_ФАЙЛА_СТАТЬИ_inc- относительно текущего каталога
- если файл - это имя класса, то ищется файл
.javaили.groovy, соответствующий классу
Например, мы имеем статью folder1/my-doc1.md и в ней описана вставка кода:
@@code file=file1.java
Тогда будут искаться следующие файлы:
folder1/_inc/my-doc1/file.javafolder1/_inc/my_doc1/file.javafolder1/_inc/file.javafolder1/file.java
Первый найденный будет использован.
В случае, если в качестве файла указано имя класса:
@@code file=pak1.pak2.Class1
Будут искаться следующие файлы:
/pak1/pak2/Class1.java/pak1/pak2/Class1.groovy
Поименнованные фрагменты файла
В некоторых типах файлов можно определять поименнованные фрагменты, которые позволяют вставлять не весь текст файла, а только его часть.
java/groovy/js
Начало фрагмента определяется коментарием //= PART-NAME, конец фрагмента - //=.
Начало фрагмента является концом предыдущего, поэтому если фрагменты идут один
за другим, конец фрагмента можно не указывать.
Пример:
def s = "hello"
//= part1
def n1 = 1
//= part2
def n2 = 2
//=
def n0 = 0
//= part3
def n3 = 3
//=
В этом примере определены 3 фрагмента со следующим содержимым:
Фрагмент part1:
def n1 = 1
Фрагмент part2:
def n2 = 2
Фрагмент part3:
def n3 = 3
В качестве имени фрагмента можно указать имя метода. В этом случае в качестве фрагмента
будет использоватся тело метода. Если тело метода содержит фрагмент body, то этот
фрагмент будет использоватся в качестве тела метода. Фрагмент с именем имяМетода-all
содержит полное тело метода, без учета фрагмента body.
Пример:
class A1 {
void m1() {
def n1 = 1
}
void m2() {
def n2 = 2
//= body
def n3 = 3
//=
def n4 = 4
}
}
В этом примере определены фрагменты:
Фрагмент m1:
def n1 = 1
Фрагмент m2:
def n3 = 3
Фрагмент m2-all:
def n2 = 2
def n3 = 3
def n4 = 4
xml/html
Начало фрагмента определяется коментарием <!-- = PART-NAME -->,
конец фрагмента - <!-- = -->.
Начало фрагмента является концом предыдущего, поэтому если фрагменты идут один
за другим, конец фрагмента можно не указывать.
Если PART-NAME указан в формате PART-NAME:PATH, то фрагмент будет
обернут в xml, который соответствует пути.
Например для такого файла:
<?xml version="1.0" encoding="utf-8"?>
<root>
<node1>
<node2>
<!-- = node3 -->
<node3/>
<!-- = -->
<!-- = node4:root/example -->
<node4/>
<!-- = -->
</node2>
</node1>
</root>Будут такие фрагменты:
<node3/><root>
<example>
<node4/>
</example>
</root>vue
Для vue-файла опредляются фрагменты: template, script, style.
Текст фрагмента - тело соответсвующего раздела vue-файла.
Внутри скриптов и шаблона можно определять свои фрагменты.
В скрипте - по правилам фрагментов 'js', в шаблоне - по правилам фрагментов 'xml'.
Например для такого файла:
<template>
<div>
</div>
</template>
<script>
export default {
props: {},
//= data1
data() {
return {}
},
//=
methods: {},
}
</script>
<style>
.a {
color: red;
}
</style>
Будут такие фрагменты:
<div>
</div>export default {
props: {},
data() {
return {}
},
methods: {},
}.a {
color: red;
}data() {
return {}
},Генерация файлов для вставки
Для генерации файлов для вставки, создайте файл groovy (или java) в проекте с классом,
наследником от jandcode.mdoc.cm.BaseCodeGen.
Любой публичный метод без параметров в таком классе - код генерации текста.
Для использования генератора укажите в атрибуте file имя файла с генератором
и после знака '#' имя его метода.
Если расширение файла не указано, подразумевается расширение .groovy или .java.
Дополнительно доступен атрибут mode со значениями:
out- (по умолчанию) показывается то, что выводитoutText.body- тело методаbodyout- тело метода в перемешку с выводом
Пример:
import jandcode.commons.variant.*
import jandcode.mdoc.builder.*
import jandcode.mdoc.cm.*
/**
* Пример генератора файлов для команды @@code
*/
class CodeGen1 extends BaseCodeGen {
/**
* Метод генерации.
* Должен вернуть строку с содержимым виртуального файла.
*/
void gen1() {
// Доступно:
// Атрибуты, переданные в команде @@code (IVariantMap с расширениями).
// Из списка атрибутов исключены file, part, lang, title (они обрабатываются
// командой @@code).
Attrs attrs = getAttrs() // class: jandcode.mdoc.cm.BaseCodeGen.Attrs
// Установить расширение генерируемого файла.
// По умолчанию - txt
setExt("txt")
// В контексте какого OutBuilder выполняется.
OutBuilder builder = getOutBuilder()
// class: jandcode.mdoc.builder.OutBuilder
// В контексте какого OutFile выполняется.
OutFile outFile = getOutFile() // class: jandcode.mdoc.builder.OutFile
// Общий кеш, который существует все время работы outBuilder.
IVariantMap cache = getCache()
// Кеш для текущего класса, который существует все время работы outBuilder.
IVariantMap cacheThis = getCacheThis()
// возвращаем текст для вставки в @@code
outText("generated text for attrs: ${attrs}")
}
/**
* Еще один метод генерации.
*/
void gen2() {
outText("generated 2 text for attrs: ${attrs}")
}
}Использование:
@@code file=CodeGen1#gen1 attr1=1 attr2=2
Результат:
generated text for attrs: [attr1:1, attr2:2, $list:[file=CodeGen1#gen1, attr1=1, attr2=2]]Использование mode=body:
@@code file=CodeGen1#gen1 attr1=1 attr2=2 mode=body
Результат:
// Доступно:
// Атрибуты, переданные в команде @@code (IVariantMap с расширениями).
// Из списка атрибутов исключены file, part, lang, title (они обрабатываются
// командой @@code).
Attrs attrs = getAttrs() // class: jandcode.mdoc.cm.BaseCodeGen.Attrs
// Установить расширение генерируемого файла.
// По умолчанию - txt
setExt("txt")
// В контексте какого OutBuilder выполняется.
OutBuilder builder = getOutBuilder()
// class: jandcode.mdoc.builder.OutBuilder
// В контексте какого OutFile выполняется.
OutFile outFile = getOutFile() // class: jandcode.mdoc.builder.OutFile
// Общий кеш, который существует все время работы outBuilder.
IVariantMap cache = getCache()
// Кеш для текущего класса, который существует все время работы outBuilder.
IVariantMap cacheThis = getCacheThis()
// возвращаем текст для вставки в @@code
outText("generated text for attrs: ${attrs}")Использование mode=bodyout:
@@code file=CodeGen1#gen1 attr1=1 attr2=2 mode=bodyout
Результат:
// Доступно:
// Атрибуты, переданные в команде @@code (IVariantMap с расширениями).
// Из списка атрибутов исключены file, part, lang, title (они обрабатываются
// командой @@code).
Attrs attrs = getAttrs() // class: jandcode.mdoc.cm.BaseCodeGen.Attrs
// Установить расширение генерируемого файла.
// По умолчанию - txt
setExt("txt")
// В контексте какого OutBuilder выполняется.
OutBuilder builder = getOutBuilder()
// class: jandcode.mdoc.builder.OutBuilder
// В контексте какого OutFile выполняется.
OutFile outFile = getOutFile() // class: jandcode.mdoc.builder.OutFile
// Общий кеш, который существует все время работы outBuilder.
IVariantMap cache = getCache()
// Кеш для текущего класса, который существует все время работы outBuilder.
IVariantMap cacheThis = getCacheThis()
// возвращаем текст для вставки в @@code
// generated text for attrs: [attr1:1, attr2:2, mode:bodyout, $list:[file=CodeGen1#gen1, attr1=1, attr2=2, mode=bodyout]]