From 9be6b4caaef6e7d2c8b140550a83c286d74b443e Mon Sep 17 00:00:00 2001 From: baoqianz <65844328+baoqianz@users.noreply.github.com> Date: Mon, 29 Jul 2024 02:39:03 +0800 Subject: [PATCH] linear layout --- index.html | 1013 ++++++++++++++++------------------------------------ 1 file changed, 309 insertions(+), 704 deletions(-) diff --git a/index.html b/index.html index 21c60c37..784159a6 100644 --- a/index.html +++ b/index.html @@ -4,37 +4,27 @@ Docco - - + + -
-
- -
- -
  def run(args = args) {
+        
+          
  def run(args = args) {
     before()
     o = new Docco(args: args, tasks: tasks)
     o.run()
-    after()
- - - - -
  • -
    - -
    - § -
    -

    Public API

    + after()
    + + + +

    Public API

    -
  • - -
        this.exports = [
    +        
    +          
        this.exports = [
           run: o::run,
           document: o::document,
           parse: o::parse,
    @@ -238,76 +163,44 @@ 

    The Groovy Script & Main Function

    version: o.version, thisScript: this, ] - }
    - - - - -
  • -
    - -
    - § -
    -

    Docco (Business Logics Follow)

    + }
    + + + +

    Docco (Business Logics Follow)

    -
  • - - - - -
  • -
    - -
    - § -
    - -
    - -
      @Log
    -  class Docco {
    - -
  • - - -
  • -
    - -
    - § -
    -

    Helpers & Initial Setup

    + + + + + +
      @Log
    +  class Docco {
    + + + +

    Helpers & Initial Setup

    -
    - -
        def __dirname = new File("").getAbsolutePath()
    +        
    +          
        def __dirname = new File("").getAbsolutePath()
         def _ = new Underscore()
         def JSON = new Json()
         def fs   = new FS()
         def path = new Path()
         def highlightjs = new HighlightJS()
         def marked = new CommonMark()
    -    def commander = new Commander()
    - -
  • - - -
  • -
    - -
    - § -
    -

    Main Documentation Generation Functions

    + def commander = new Commander()
    + + + +

    Main Documentation Generation Functions

    Generate the documentation for our configured source file by copying over static assets, reading all the source files in, splitting them up into prose+code sections, highlighting each file in the appropriate language, and printing them out in an HTML template.

    - - -
        def document(options = [:], k = null) {
    +        
    +          
        def document(options = [:], k = null) {
           def config = configure options
       
           fs.mkdirs(config.output) { ->
    @@ -343,25 +236,17 @@ 

    Docco (Business Logics Follow)

    if (files.size()) nextFile() } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Given a string of source code, parse out each block of prose and the code that + }

    + + + +

    Given a string of source code, parse out each block of prose and the code that follows it — by detecting which is which, line by line — and then create an individual section for it. Each section is an object with docsText and codeText properties, and eventually docsHtml and codeHtml as well.

    - - -
        def parse(source, code, config = [:]) {
    +        
    +          
        def parse(source, code, config = [:]) {
           def lines    = code.split "\n"
           def sections = []
           def lang     = getLanguage source, config
    @@ -370,24 +255,16 @@ 

    Docco (Business Logics Follow)

    def save = { -> sections.add([docsText: docsText, codeText: codeText]) hasCode = docsText = codeText = '' - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Our quick-and-dirty implementation of the literate programming style. Simply + }

    + + + +

    Our quick-and-dirty implementation of the literate programming style. Simply invert the prose and code relationship on a per-line basis, and then continue as normal below.

    - - -
          if (lang.literate) {
    +        
    +          
          if (lang.literate) {
             def isText = true, maybeCode = true
             def match
             for (def line in lines) {
    @@ -424,24 +301,16 @@ 

    Docco (Business Logics Follow)

    save() sections - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    To format and highlight the now-parsed sections of code, we use Highlight.js + }

    + + + +

    To format and highlight the now-parsed sections of code, we use Highlight.js over stdio, and run the text of their corresponding comments through Markdown, using CommonMark.

    - - -
        def format(source, sections, config) {
    +        
    +          
        def format(source, sections, config) {
           def language      = getLanguage source, config
           def markedOptions = [smartypants: true]
       
    @@ -470,24 +339,16 @@ 

    Docco (Business Logics Follow)

    section.codeHtml = "<div class='highlight'><pre>${code}</pre></div>" section.docsHtml = marked.apply(section.docsText) } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Once all of the code has finished highlighting, we can write the resulting + }

    + + + +

    Once all of the code has finished highlighting, we can write the resulting documentation file by passing the completed HTML sections into the template, and rendering it to the specified output path.

    - - -
        def write(source, sections, config) {
    +        
    +          
        def write(source, sections, config) {
           def first
       
           def destination = { file ->
    @@ -498,23 +359,15 @@ 

    Docco (Business Logics Follow)

    def to = path.dirname(path.resolve(file)) def from = path.dirname(path.resolve(destination(source))) path.join(path.relative(from, to), path.basename(file)) - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    The title of the file is either the first heading in the prose, or the + }

    + + + +

    The title of the file is either the first heading in the prose, or the name of the source file.

    - - -
          def firstSection = _.find sections, { section ->
    +        
    +          
          def firstSection = _.find sections, { section ->
             section.docsText.size() > 0
           }
           if (firstSection) first = marked.lexer(firstSection.docsText).firstChild
    @@ -529,24 +382,16 @@ 

    Docco (Business Logics Follow)

    println "docco: ${source} -> ${destination source}" fs.outputFileSync destination(source), html - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Configuration

    + }
    + + + +

    Configuration

    Default configuration options. All of these may be extended by user-specified options.

    - - -
        def defaults = [
    +        
    +          
        def defaults = [
           layout:     'parallel',
           output:     'docs',
           template:   null,
    @@ -554,45 +399,29 @@ 

    Docco (Business Logics Follow)

    extension: null, languages: [:], marked: null - ]
    - -
  • - - -
  • -
    - -
    - § -
    -

    Configure this particular run of Docco. We might use a passed-in external + ]

    + + + +

    Configure this particular run of Docco. We might use a passed-in external template, or one of the built-in layouts. We only attempt to process source files for languages for which we have definitions.

    - - -
        def configure(options) {
    +        
    +          
        def configure(options) {
           def config = _.extend([:], defaults, _.pick(options.opts(), _.keys(defaults)))
       
    -      config.languages = buildMatchers config.languages
    - -
  • + config.languages = buildMatchers config.languages + -
  • -
    - -
    - § -
    -

    The user is able to override the layout file used with the --template parameter. +

    The user is able to override the layout file used with the --template parameter. In this case, it is also neccessary to explicitly specify a stylesheet file. These custom templates are compiled exactly like the predefined ones, but the public folder is only copied for the latter.

    -
    - -
          if (options.template) {
    +        
    +          
          if (options.template) {
             if (!options.css) {
               log.info "docco: no stylesheet file specified"
             }
    @@ -620,90 +449,50 @@ 

    Docco (Business Logics Follow)

    }).sort() config - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Languages are stored in JSON in the file resources/languages.json. + }

    + + + +

    Languages are stored in JSON in the file resources/languages.json. Each item maps the file extension to the name of the language and the symbol that indicates a line comment. To enroll a new programming language to Docco, just add it to the file.

    - - -
        def languages = JSON.parse fs.readFileSync(path.join(__dirname, 'resources', 'languages.json'))
    - -
  • - - -
  • -
    - -
    - § -
    -

    Build out the appropriate matchers and delimiters for each language.

    + +
        def languages = JSON.parse fs.readFileSync(path.join(__dirname, 'resources', 'languages.json'))
    + + + +

    Build out the appropriate matchers and delimiters for each language.

    -
    - -
        def buildMatchers(languages) {
    -      languages.each { ext, l ->
    - -
  • - - -
  • -
    - -
    - § -
    -

    Does the line begin with a comment?

    + +
        def buildMatchers(languages) {
    +      languages.each { ext, l ->
    + + + +

    Does the line begin with a comment?

    -
    - -
            l.commentMatcher = ~/^\s*${l.symbol}\s?/
    - -
  • - - -
  • -
    - -
    - § -
    -

    Ignore hashbangs and interpolations...

    + +
            l.commentMatcher = ~/^\s*${l.symbol}\s?/
    + + + +

    Ignore hashbangs and interpolations...

    -
    - -
            l.commentFilter = $/(^#![/]|^\s*#\${'{'})/$
    +        
    +          
            l.commentFilter = $/(^#![/]|^\s*#\${'{'})/$
           }
           languages
    -    }
    - -
  • - - -
  • -
    - -
    - § -
    -

    A function to get the current language we're documenting, based on the + }

    + + + +

    A function to get the current language we're documenting, based on the file extension. Detect and tag "literate" .ext.md variants.

    - - -
        def getLanguage(source, config) {
    +        
    +          
        def getLanguage(source, config) {
           def ext  = config.extension ?: path.extname(source) ?: path.basename(source)
           def lang = config.languages?[ext] ?: languages[ext]
           if (lang && lang.name == 'markdown') {
    @@ -714,39 +503,23 @@ 

    Docco (Business Logics Follow)

    } } lang - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Keep it DRY. Extract the docco version from package.json

    + }
    + + + +

    Keep it DRY. Extract the docco version from package.json

    - - -
        def version = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'))).version
    - -
  • - - -
  • -
    - -
    - § -
    -

    Command Line Interface

    + +
        def version = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'))).version
    + + + +

    Command Line Interface

    Finally, let's define the interface to run Docco from the command line. Parse options using CliBuilder.

    -
    - -
        def run(args = args) {
    +        
    +          
        def run(args = args) {
           def c = defaults
           commander.version(version)
             .usage('groovy docco.groovy [options] files')
    @@ -774,61 +547,29 @@ 

    Docco (Business Logics Follow)

    args = context.args languages = buildMatchers languages } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Helper Classes Follow

    + }
    + + + +

    Helper Classes Follow

    - - -
  • - - -
  • -
    - -
    - § -
    -

    ==========================

    + + + +

    ==========================

    -
    - -
  • - - -
  • -
    - -
    - § -
    -

    Code Highlight Patch

    + + + +

    Code Highlight Patch

    -
    - -
  • - - -
  • -
    - -
    - § -
    -

    ECMAScript

    + + + +

    ECMAScript

    -
    - -
      @CompileStatic
    +        
    +          
      @CompileStatic
       class ECMAScript {
         static final String IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*'
         static final String[] KEYWORDS = [
    @@ -980,22 +721,14 @@ 

    Code Highlight Patch

    BUILT_IN_GLOBALS + TYPES + ERROR_TYPES - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Coffeescript

    + }
    + + + +

    Coffeescript

    - - -
      @CompileStatic
    +        
    +          
      @CompileStatic
       class CoffeescriptLanguage implements LanguageBuilder {
         private static String[] ALIASES = ['coffee']
         private static String IDENT_RE = '[A-Za-z$_][0-9A-Za-z$_]*'
    @@ -1142,34 +875,18 @@ 

    Code Highlight Patch

    ]) .illegal(/\/\*/) } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    JavaObjectMethods

    + }
    + + + +

    JavaObjectMethods

    - - -
  • - - -
  • -
    - -
    - § -
    - -
    - -
      @CompileStatic
    +        
    +      
    +        
    +        
    +        
    +          
      @CompileStatic
       class JavaObjectMethods {
         static void setProperty(Class clazz, obj, String property, value) {
           def field = clazz.getDeclaredField(property)
    @@ -1180,22 +897,14 @@ 

    JavaObjectMethods

    MH.invokeWithArguments(value) : MH.invokeWithArguments(obj, value) } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    FS

    + }
    + + + +

    FS

    - - -
      class FS {
    +        
    +          
      class FS {
         def antBuilder = new AntBuilder()
       
         def mkdirs(path, k) {
    @@ -1249,34 +958,18 @@ 

    FS

    FS() { antBuilder.project.listeners[0].msgOutputLevel = 1 } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Path

    + }
    + + + +

    Path

    - - -
  • - - -
  • -
    - -
    - § -
    - -
    - -
      class Path {
    +        
    +      
    +        
    +        
    +        
    +          
      class Path {
         def resolve(path) {
           new File(path).getAbsolutePath()
         }
    @@ -1332,34 +1025,18 @@ 

    Path

    join(paths[1..-1] as String[]) } } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Markdown

    + }
    + + + +

    Markdown

    - - -
  • - - -
  • -
    - -
    - § -
    - -
    - -
      class CommonMark {
    +        
    +      
    +        
    +        
    +        
    +          
      class CommonMark {
         def parser = Parser.builder().build()
         def renderer = MarkdownHtmlRenderer.builder().build()
         def apply(String md) {
    @@ -1373,34 +1050,18 @@ 

    Markdown

    def setOptions(HashMap options) { // TODO: inline code block highlighting } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    highlight.js

    + }
    + + + +

    highlight.js

    - - -
  • - - -
  • -
    - -
    - § -
    - -
    - -
      class HighlightJS {
    +        
    +      
    +        
    +        
    +        
    +          
      class HighlightJS {
         def highlighter = new Highlighter<CharSequence>(new RendererFactory());
         def getLanguage(String name) {
           Highlighter.findLanguage(name)
    @@ -1418,22 +1079,14 @@ 

    highlight.js

    StyleRenderer<CharSequence> create(String languageName) { return new HtmlRenderer("hljs-"); } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Add support for coffeescript code highlighting

    + }
    + + + +

    Add support for coffeescript code highlighting

    - - -
        HighlightJS() {
    +        
    +          
        HighlightJS() {
           Highlighter.registerLanguage(
             "coffeescript",
             Highlighter.mLanguageMap,
    @@ -1446,34 +1099,18 @@ 

    highlight.js

    (String[])(Highlighter.mLanguages + new String[] { "coffeescript" }) ) } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Underscore

    + }
    + + + +

    Underscore

    - - -
  • - - -
  • -
    - -
    - § -
    - -
    - -
      class Underscore {
    +        
    +      
    +        
    +        
    +        
    +          
      class Underscore {
         def t = new StreamingTemplateEngine()
         def find(list, Closure predicate) {
           list.find predicate
    @@ -1515,34 +1152,18 @@ 

    Underscore

    def template(templateString) { t.createTemplate(templateString)::make } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    JSON

    + }
    + + + +

    JSON

    - - -
  • - - -
  • -
    - -
    - § -
    - -
    - -
      class Json {
    +        
    +      
    +        
    +        
    +        
    +          
      class Json {
         def jsonSlurper = new JsonSlurper()
         def parse(String text) {
           jsonSlurper.parseText(text)
    @@ -1551,34 +1172,18 @@ 

    JSON

    def stringify(object) { JsonOutput.toJson(object) } - }
    - -
  • - - -
  • -
    - -
    - § -
    -

    Commander

    + }
    + + + +

    Commander

    - - -
  • - - -
  • -
    - -
    - § -
    - -
    - -
      class Commander {
    +        
    +      
    +        
    +        
    +        
    +          
      class Commander {
         def cli     = new CliBuilder(stopAtNonOption: false)
         def options = null
       
    @@ -1670,11 +1275,11 @@ 

    Commander

    DoccoMain(Binding context) { super(context) } -}
    - -
  • +} - + +
    h
    +